dgraph-io/dgraph · error

Indexing not allowed on predicate %s of type %s

Error message

Indexing not allowed on predicate %s of type %s

What it means

When applying a schema update, resolveTokenizers rejects an @index directive on predicates whose type cannot be indexed: uid, default (untyped), or password. These types have no tokenizers, so indexing them is meaningless and the schema is refused. The error names the predicate (via x.ParseAttr) and its type.

Source

Thrown at schema/parse.go:420

	optVal := nextItem.Val[1 : len(nextItem.Val)-1]
	return &pb.OptionPair{Key: optName, Value: optVal}, nil
}

func HasTokenizerOrVectorIndexSpec(update *pb.SchemaUpdate) bool {
	if update == nil {
		return false
	}
	return len(update.Tokenizer) > 0 || len(update.IndexSpecs) > 0
}

// resolveTokenizers resolves default tokenizers and verifies tokenizers definitions.
func resolveTokenizers(updates []*pb.SchemaUpdate) error {
	for _, schema := range updates {
		typ := types.TypeID(schema.ValueType)

		if (typ == types.UidID || typ == types.DefaultID || typ == types.PasswordID) &&
			schema.Directive == pb.SchemaUpdate_INDEX {
			return errors.Errorf("Indexing not allowed on predicate %s of type %s",
				x.ParseAttr(schema.Predicate), typ.Name())
		}

		if typ == types.UidID {
			continue
		}

		if !HasTokenizerOrVectorIndexSpec(schema) &&
			schema.Directive == pb.SchemaUpdate_INDEX {
			return errors.Errorf(
				"Require type of tokenizer for pred: %s of type: %s for indexing.",
				schema.Predicate, typ.Name())
		} else if HasTokenizerOrVectorIndexSpec(schema) &&
			schema.Directive != pb.SchemaUpdate_INDEX {
			return errors.Errorf("Tokenizers present without indexing on attr %s",
				x.ParseAttr(schema.Predicate))
		}
		// check for valid tokenizer types and duplicates

View on GitHub (pinned to 759e242be6)

Solutions

  1. Remove the @index directive from uid/default/password predicates.
  2. Give the predicate a concrete indexable type (string, int, float, bool, datetime, etc.) if you truly need indexing.
  3. If you need to look up users by password-like fields, store a separate hash/salted field of type string with an appropriate tokenizer.
  4. Re-run the schema alteration after fixing the type/directive combination.

Example fix

// before
user_password: password @index(exact) .
friend: [uid] @index(hash) .
// after
user_password: password .
friend: [uid] .
lookup_key: string @index(exact) .
Defensive patterns

Strategy: validation

Validate before calling

const nonIndexable = new Set(['uid', 'default', 'password']);
function validateSchemaLine(line) {
  const m = line.match(/^(\w+):\s*([\w\[\]]+)\s*(\.[^.]*)?@index/);
  if (m && nonIndexable.has(m[2].replace(/\[|\]/g, ''))) {
    throw new Error(`@index not allowed on ${m[1]} of type ${m[2]}`);
  }
}

Try / catch

try {
  await dgraph.Alter(ctx, op);
} catch (e) {
  if (String(e).includes('Indexing not allowed on predicate')) {
    // strip @index from uid/default/password predicates and retry
  }
  throw e;
}

Prevention

When it happens

Trigger: A DQL schema alteration adding @index to a predicate declared as uid, default, or password, e.g. `name: password @index(term) .` or an @upsert/ACHEMA call marking a uid predicate with an index directive.

Common situations: Copy-pasted schema lines carrying @index onto password fields (common for intended-but-unsupported exact search on secrets); new predicates with no type yet (`pred: string` omitted so it defaults) that were given @index; migrations that blanket-apply @index to every predicate.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/6dfadcbfb58f3284. Report an issue: GitHub.