diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml
index 994dfc65268..6aa01eb0daa 100644
--- a/doc/src/sgml/ref/create_type.sgml
+++ b/doc/src/sgml/ref/create_type.sgml
@@ -186,6 +186,11 @@ CREATE TYPE name
type name. Otherwise, the multirange type name is formed by appending a
_multirange suffix to the range type name.
+
+
+ To be able to create a range type, you must have USAGE
+ privilege on the subtype.
+
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 3f3a0f9d1a3..a91185ae858 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -1514,6 +1514,10 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt)
errmsg("range subtype cannot be %s",
format_type_be(rangeSubtype))));
+ aclresult = object_aclcheck(TypeRelationId, rangeSubtype, GetUserId(), ACL_USAGE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error_type(aclresult, rangeSubtype);
+
/* Identify subopclass */
rangeSubOpclass = findRangeSubOpclass(rangeSubOpclassName, rangeSubtype);
diff --git a/src/test/regress/expected/rangetypes.out b/src/test/regress/expected/rangetypes.out
index a7cc220bf0d..435c7306484 100644
--- a/src/test/regress/expected/rangetypes.out
+++ b/src/test/regress/expected/rangetypes.out
@@ -1547,6 +1547,21 @@ ERROR: range lower bound must be less than or equal to range upper bound
LINE 1: select '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)':...
^
set timezone to default;
+-- CREATE TYPE AS RANGE checks for USAGE on subtype
+CREATE ROLE regress_subtype;
+CREATE TYPE mytype AS (a INT, b INT);
+REVOKE USAGE ON TYPE mytype FROM PUBLIC;
+SET ROLE regress_subtype;
+CREATE TYPE myrange AS RANGE (subtype = mytype);
+ERROR: permission denied for type mytype
+RESET ROLE;
+GRANT USAGE ON TYPE mytype TO regress_subtype;
+SET ROLE regress_subtype;
+CREATE TYPE myrange AS RANGE (subtype = mytype);
+RESET ROLE;
+DROP TYPE mytype CASCADE;
+NOTICE: drop cascades to type myrange
+DROP ROLE regress_subtype;
--
-- Test user-defined range of floats
-- (type float8range was already made in test_setup.sql)
diff --git a/src/test/regress/sql/rangetypes.sql b/src/test/regress/sql/rangetypes.sql
index a5ecdf5372f..bad1b5afcad 100644
--- a/src/test/regress/sql/rangetypes.sql
+++ b/src/test/regress/sql/rangetypes.sql
@@ -434,6 +434,20 @@ select '[2010-01-01 01:00:00 -05, 2010-01-01 02:00:00 -08)'::tstzrange;
select '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)'::tstzrange;
set timezone to default;
+-- CREATE TYPE AS RANGE checks for USAGE on subtype
+CREATE ROLE regress_subtype;
+CREATE TYPE mytype AS (a INT, b INT);
+REVOKE USAGE ON TYPE mytype FROM PUBLIC;
+SET ROLE regress_subtype;
+CREATE TYPE myrange AS RANGE (subtype = mytype);
+RESET ROLE;
+GRANT USAGE ON TYPE mytype TO regress_subtype;
+SET ROLE regress_subtype;
+CREATE TYPE myrange AS RANGE (subtype = mytype);
+RESET ROLE;
+DROP TYPE mytype CASCADE;
+DROP ROLE regress_subtype;
+
--
-- Test user-defined range of floats
-- (type float8range was already made in test_setup.sql)