vitessio/vitess · error

Invalid UUID: %s, expected condensed 32 hexadecimals

Error message

Invalid UUID: %s, expected condensed 32 hexadecimals

What it means

GenerateInternalTableName validates that the UUID component is in condensed form: 32 hexadecimal characters with delimiters removed (isCondensedUUID). This guarantees deterministic, parseable internal table names. A non-condensed UUID (with hyphens, wrong length, or non-hex) is rejected.

Source

Thrown at go/vt/schema/name.go:114

	return condensedUUIDRegexp.MatchString(uuid)
}

// generateGCTableName creates an internal table name, based on desired hint and time, and with optional preset UUID.
// If uuid is given, then it must be in condensed-UUID format. If empty, the function auto-generates a UUID.
func GenerateInternalTableName(hint string, uuid string, t time.Time) (tableName string, err error) {
	if len(hint) != 3 {
		return "", fmt.Errorf("Invalid hint: %s, expected 3 characters", hint)
	}
	if uuid == "" {
		uuid, err = CreateUUIDWithDelimiter("")
	} else {
		uuid = condenseUUID(uuid)
	}
	if err != nil {
		return "", err
	}
	if !isCondensedUUID(uuid) {
		return "", fmt.Errorf("Invalid UUID: %s, expected condensed 32 hexadecimals", uuid)
	}
	timestamp := ToReadableTimestamp(t)
	return fmt.Sprintf("_vt_%s_%s_%s_", hint, uuid, timestamp), nil
}

// IsInternalOperationTableName answers 'true' when the given table name stands for an internal Vitess
// table used for operations such as:
// - Online DDL (gh-ost, pt-online-schema-change)
// - Table GC (renamed before drop)
// Apps such as VStreamer may choose to ignore such tables.
func IsInternalOperationTableName(tableName string) bool {
	if internalTableNameRegexp.MatchString(tableName) {
		return true
	}
	if IsGCTableName(tableName) {
		return true
	}
	if IsOnlineDDLTableName(tableName) {

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Condense the UUID first: strip delimiters/hyphens so it is exactly 32 hex chars, or pass "" to auto-generate.
  2. Use the package's condenseUUID semantics — remove '-' and verify 32 hex characters.
  3. Validate with a regexp ^[0-9a-f]{32}$ before calling.

Example fix

// before
name, err := schema.GenerateInternalTableName("rdg", u.String(), time.Now()) // hyphenated
// after
condensed := strings.ReplaceAll(u.String(), "-", "")
name, err := schema.GenerateInternalTableName("rdg", condensed, time.Now())
Defensive patterns

Strategy: validation

Validate before calling

var condensedRe = regexp.MustCompile(`^[0-9a-f]{32}$`)
if !condensedRe.MatchString(uuid) {
    uuid = strings.ReplaceAll(strings.ToLower(uuid), "-", "")
}

Type guard

func isCondensedUUID(u string) bool {
    if len(u) != 32 { return false }
    for _, c := range u {
        if !(c >= '0' && c <= '9' || c >= 'a' && c <= 'f') { return false }
    }
    return true
}

Try / catch

name, err := schema.GenerateInternalTableName(hint, uuid, now)
if err != nil {
    return fmt.Errorf("internal table name generation failed: %w", err)
}

Prevention

When it happens

Trigger: Passing a non-empty uuid argument to GenerateInternalTableName that is not condensed, e.g. a hyphenated standard UUID "6ba7b810-9dad-..." or a truncated string. Empty uuid is fine (auto-generated); anything else must pass isCondensedUUID.

Common situations: Passing a canonical hyphenated UUID (or one from google/uuid) directly; UUIDs stored with braces or uppercase hex; reusing a UUID from another system with different formatting.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/1c8990726a28077a. Report an issue: GitHub.