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
- Shorten the identifier to <= 64 bytes (a UUID string is safely 36)
- Move any metadata out of the run ID into dedicated fields/tags
- 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
- Use UUIDs as run IDs — fixed 36 bytes
- Put metadata in dedicated fields, not the ID
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
- %s cannot be empty
- %s must be valid UTF-8
- invalid transport.protocol, optional values are %v
- unexpected message type %s, want %s
- get natHoleRespMsg error: invalid message type
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/a5f4b0e7a6f54bfd.
Report an issue: GitHub.