XTLS/Xray-core · error

too long "shortIds[

Error message

too long "shortIds[

What it means

Thrown by the REALITY builder when a shortId string is longer than 16 characters. Short IDs are hex-encoded 8-byte values; 16 hex chars is the maximum, and the string is later hex-decoded into an 8-byte buffer. The message includes the index and the offending value (assembled from multiple parts in errors.New).

Source

Thrown at infra/conf/transport_security.go:141

			var u uint64
			for i, s := range strings.Split(c.MaxClientVer, ".") {
				if i == 3 {
					return nil, errors.New(`invalid "maxClientVer": `, c.MaxClientVer)
				}
				if u, err = strconv.ParseUint(s, 10, 8); err != nil {
					return nil, errors.New(`"maxClientVer[`, i, `]" should be less than 256`)
				} else {
					config.MaxClientVer[i] = byte(u)
				}
			}
		}
		if len(c.ShortIds) == 0 {
			return nil, errors.New(`empty "shortIds"`)
		}
		config.ShortIds = make([][]byte, len(c.ShortIds))
		for i, s := range c.ShortIds {
			if len(s) > 16 {
				return nil, errors.New(`too long "shortIds[`, i, `]": `, s)
			}
			config.ShortIds[i] = make([]byte, 8)
			if _, err = hex.Decode(config.ShortIds[i], []byte(s)); err != nil {
				return nil, errors.New(`invalid "shortIds[`, i, `]": `, s)
			}
		}
		config.Dest = s
		config.Type = c.Type
		config.Xver = c.Xver
		config.ServerNames = c.ServerNames
		config.MaxTimeDiff = c.MaxTimeDiff

		if c.Mldsa65Seed != "" {
			if c.Mldsa65Seed == c.PrivateKey {
				return nil, errors.New(`"mldsa65Seed" and "privateKey" can not be the same value: `, c.Mldsa65Seed)
			}
			if config.Mldsa65Seed, err = base64.RawURLEncoding.DecodeString(c.Mldsa65Seed); err != nil || len(config.Mldsa65Seed) != 32 {
				return nil, errors.New(`invalid "mldsa65Seed": `, c.Mldsa65Seed)

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Use 0-16 hex characters, e.g. "6ba85179e30d4fc2".
  2. Generate with 'openssl rand -hex 8' (or fewer bytes) if you need randomness.
  3. Note odd-length hex strings also fail the later hex.Decode (invalid shortIds[i]) — keep the length even.

Example fix

// before
"shortIds": ["6ba85179e30d4fc2-extra"]
// after
"shortIds": ["6ba85179e30d4fc2"]
Defensive patterns

Strategy: validation

Validate before calling

for i, id := range reality.ShortIds {
    if len(id) > 16 || len(id)%2 != 1 && !isHex(id) { /* check */ }
}
// simpler strict form:
var shortIdRe = regexp.MustCompile(`^([0-9a-fA-F]{2})*$`)
func validShortId(s string) bool { return len(s) <= 16 && shortIdRe.MatchString(s) }

Prevention

When it happens

Trigger: Setting a shortId like "0123456789abcdef0" (17+ chars), or pasting a UUID or random base64 blob into the field.

Common situations: Generating tokens with uuidgen or openssl rand -base64 instead of hex, or concatenating two shortIds by accident.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/06c9108a13d771c3. Report an issue: GitHub.