go-playground/validator · critical

Invalid validation tag on field '%s'

Error message

Invalid validation tag on field '%s'

What it means

A tag segment parsed to an empty validator name (e.g. a leading/trailing comma or `,|,` leaving an empty tag before params). cache.go panics with "Invalid validation tag on field '<FieldName>'" when building the tag cache for the struct.

Source

Thrown at cache.go:286

			for j := 0; j < len(orVals); j++ {
				vals := strings.SplitN(orVals[j], tagKeySeparator, 2)
				if noAlias {
					alias = vals[0]
					current.aliasTag = alias
				} else {
					current.actualAliasTag = t
				}

				if j > 0 {
					current.next = &cTag{aliasTag: alias, actualAliasTag: current.actualAliasTag, hasAlias: hasAlias, hasTag: true}
					current = current.next
				}
				current.hasParam = len(vals) > 1

				current.tag = vals[0]
				if len(current.tag) == 0 {
					panic(strings.TrimSpace(fmt.Sprintf(invalidValidation, fieldName)))
				}

				if wrapper, ok := v.validations[current.tag]; ok {
					current.fn = wrapper.fn
					current.runValidationWhenNil = wrapper.runValidationOnNil
				} else if aliasTag, isAlias := v.aliases[current.tag]; isAlias {
					aliasFirst, aliasLast := v.parseFieldTagsRecursive(aliasTag, fieldName, current.tag, true)

					current.tag = aliasFirst.tag
					current.fn = aliasFirst.fn
					current.runValidationWhenNil = aliasFirst.runValidationWhenNil
					current.hasParam = aliasFirst.hasParam
					current.param = aliasFirst.param
					current.typeof = aliasFirst.typeof
					current.hasAlias = true

					if aliasFirst.next != nil {
						nextInChain := current.next

View on GitHub (pinned to facf128d2e)

Solutions

  1. Remove empty tag entries / duplicate commas from the struct tag
  2. Fix the code that generates the tag string so it never emits an empty segment
  3. Check aliases: an alias expanding to an empty string produces this panic
  4. Add a startup test validating a representative struct instance to fail fast

Example fix

// before
Name string `validate:",required"`
// after
Name string `validate:"required"`
Defensive patterns

Strategy: validation

Validate before calling

func checkEmptyTags(t reflect.StructTag) error {
    for i, tg := range strings.Split(t.Get("validate"), ",") {
        if strings.TrimSpace(tg) == "" {
            return fmt.Errorf("empty tag segment at index %d", i)
        }
    }
    return nil
}

Try / catch

func validateStrict(s any) (err error) {
    defer func() {
        if r := recover(); r != nil {
            if strings.Contains(fmt.Sprint(r), "Invalid validation tag") {
                err = fmt.Errorf("malformed struct tag: %v", r)
            } else { panic(r) }
        }
    }()
    return validate.Struct(s)
}

Prevention

When it happens

Trigger: Struct tag containing empty tag entries such as `validate:",required"`, `validate:"required,,min=1"`, or an alias expanding to an empty tag; malformed tags from code-generated structs.

Common situations: String-built tags where variables are empty (fmt.Sprintf("validate:%s,%s", emptyVar, "required")); trailing commas after refactors; ORM/struct generators emitting extra commas.

Related errors


AI-assisted analysis of go-playground/validator@facf128d2e (2026-09-02). Data as JSON: /api/errors/f3e40bf5a2e90606. Report an issue: GitHub.