fatedier/frp · error

%s is too long: length %d exceeds maximum %d

Error message

%s is too long: length %d exceeds maximum %d

What it means

The identifier (e.g. run ID, capped at MaxRunIDLength = 64 bytes) exceeds its byte-length limit. Length is measured in bytes via len(), not runes, so multi-byte UTF-8 content hits the cap faster. This guard prevents unbounded identifiers from bloating control-plane state and messages.

Source

Thrown at pkg/config/v1/validation/name.go:33

package validation

import (
	"fmt"
	"unicode"
	"unicode/utf8"
)

const (
	// MaxRunIDLength is the maximum number of bytes accepted for a control run ID.
	MaxRunIDLength = 64
)

func validateIdentifier(value, kind string, maxLength int) error {
	if value == "" {
		return fmt.Errorf("%s cannot be empty", kind)
	}
	if len(value) > maxLength {
		return fmt.Errorf("%s is too long: length %d exceeds maximum %d", kind, len(value), maxLength)
	}
	if !utf8.ValidString(value) {
		return fmt.Errorf("%s must be valid UTF-8", kind)
	}
	for _, r := range value {
		if !unicode.IsPrint(r) {
			return fmt.Errorf("%s contains non-printable character", kind)
		}
	}
	return nil
}

func ValidateRunID(runID string) error {
	return validateIdentifier(runID, "run id", MaxRunIDLength)
}

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Shorten the identifier to <= 64 bytes (a UUID string is safely 36)
  2. Move any metadata out of the run ID into dedicated fields/tags
  3. Add a length check in your client code before sending the login message

Example fix

// before
runID := fmt.Sprintf("%s-%s-%s", hostname, jwtToken, timestamp)
// > 64 bytes

// after
runID := uuid.NewString() // 36 bytes
Defensive patterns

Strategy: validation

Validate before calling

func runIDFits(s string) bool { return len(s) <= validation.MaxRunIDLength }

Type guard

func isValidRunID(s string) bool {
    return s != "" && len(s) <= validation.MaxRunIDLength
}

Prevention

When it happens

Trigger: ValidateRunID called with a value longer than 64 bytes — e.g. a custom client stuffing a JWT, hostname+UUID+timestamp, or certificate DN into RunID.

Common situations: Custom integrations deriving run IDs from long tokens; embedding metadata in the ID field; switching from UUID (36 chars) to a composite string that quietly crossed 64 bytes.

Related errors


AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15). Data as JSON: /api/errors/a5f4b0e7a6f54bfd. Report an issue: GitHub.