diff --git a/sdk/helper/consts/replication.go b/sdk/helper/consts/replication.go
index 55cfc4ae34b6d5010caac2e239ce3e75b0840aa8..546f533ee393fc2dda0d9f74f0d731e1771f2401 100644
--- a/sdk/helper/consts/replication.go
+++ b/sdk/helper/consts/replication.go
@@ -18,6 +18,7 @@ const (
 	// manager.  It should contain a character that is not allowed in secondary
 	// ids to ensure it doesn't collide.
 	CurrentReplicatedSecondaryIdentifier = ".current"
+	CoreFeatureFlagPath                  = "core/cluster/feature-flags"
 )
 
 type ReplicationState uint32
diff --git a/vault/core.go b/vault/core.go
index 263ef00305f76e739214cf794c399316c651ffce..b7180bae204ed258210b06ec8922b3c8d9df202a 100644
--- a/vault/core.go
+++ b/vault/core.go
@@ -1825,6 +1825,14 @@ func (s standardUnsealStrategy) unseal(ctx context.Context, logger log.Logger, c
 	if err := enterprisePostUnseal(c); err != nil {
 		return err
 	}
+	if !c.ReplicationState().HasState(consts.ReplicationPerformanceSecondary | consts.ReplicationDRPrimary | consts.ReplicationDRSecondary) {
+		// Only perf primarys should write feature flags, but we do it by
+		// excluding other states so that we don't have to change it when
+		// a non-replicated cluster becomes a primary.
+		if err := c.persistFeatureFlags(ctx); err != nil {
+			return err
+		}
+	}
 
 	if !c.IsDRSecondary() {
 		if err := c.ensureWrappingKey(ctx); err != nil {
@@ -2330,3 +2338,34 @@ type BuiltinRegistry interface {
 func (c *Core) AuditLogger() AuditLogger {
 	return &basicAuditor{c: c}
 }
+
+type FeatureFlags struct {
+	NamespacesCubbyholesLocal bool `json:"namespace_cubbyholes_local"`
+}
+
+func (c *Core) persistFeatureFlags(ctx context.Context) error {
+	c.logger.Debug("persisting feature flags")
+	json, err := jsonutil.EncodeJSON(&FeatureFlags{NamespacesCubbyholesLocal: !c.PR1103disabled})
+	if err != nil {
+		return err
+	}
+	return c.barrier.Put(ctx, &logical.StorageEntry{
+		Key:   consts.CoreFeatureFlagPath,
+		Value: json,
+	})
+}
+
+func (c *Core) readFeatureFlags(ctx context.Context) (*FeatureFlags, error) {
+	entry, err := c.barrier.Get(ctx, consts.CoreFeatureFlagPath)
+	if err != nil {
+		return nil, err
+	}
+	var flags FeatureFlags
+	if entry != nil {
+		err = jsonutil.DecodeJSON(entry.Value, &flags)
+		if err != nil {
+			return nil, err
+		}
+	}
+	return &flags, nil
+}
diff --git a/vendor/github.com/hashicorp/vault/sdk/framework/path.go b/vendor/github.com/hashicorp/vault/sdk/framework/path.go
index 8f5dd5bee107d858c94e8076159df925d6fe4b06..87ba5d43e041c386f37fa4b9b40398def85197c3 100644
--- a/vendor/github.com/hashicorp/vault/sdk/framework/path.go
+++ b/vendor/github.com/hashicorp/vault/sdk/framework/path.go
@@ -190,8 +190,8 @@ type DisplayAttributes struct {
 	// Action is the verb to use for the operation.
 	Action string `json:"action,omitempty"`
 
-	// EditType is the type of form field needed for a property
-	// e.g. "textarea" or "file"
+	// EditType is the optional type of form field needed for a property
+	// This is only necessary for a "textarea" or "file"
 	EditType string `json:"editType,omitempty"`
 }
 
diff --git a/vendor/github.com/hashicorp/vault/sdk/helper/consts/replication.go b/vendor/github.com/hashicorp/vault/sdk/helper/consts/replication.go
index 55cfc4ae34b6d5010caac2e239ce3e75b0840aa8..546f533ee393fc2dda0d9f74f0d731e1771f2401 100644
--- a/vendor/github.com/hashicorp/vault/sdk/helper/consts/replication.go
+++ b/vendor/github.com/hashicorp/vault/sdk/helper/consts/replication.go
@@ -18,6 +18,7 @@ const (
 	// manager.  It should contain a character that is not allowed in secondary
 	// ids to ensure it doesn't collide.
 	CurrentReplicatedSecondaryIdentifier = ".current"
+	CoreFeatureFlagPath                  = "core/cluster/feature-flags"
 )
 
 type ReplicationState uint32