grpc-ecosystem/grpc-gateway · error

expected EOF but got

Error message

expected EOF but got %q

What it means

Token-mismatch error from parser.accept when the parser required end-of-input but tokens remain (or the token stream is malformed). It fires from topLevelSegments' final accept(typeEOF) check; the message shows the unexpected token still pending.

Solutions

  1. Remove trailing garbage after the path template in the HttpRule pattern.
  2. Ensure braces/wildcards are balanced so the template ends cleanly.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at internal/httprule/parse.go:256 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of grpc-ecosystem/grpc-gateway@a58a4436a3 (2026-09-02). Data as JSON: /api/errors/eb6327c97a6ea6e1. Report an issue: GitHub.

Appendix: source

Thrown at internal/httprule/parse.go:256

	typeEOF     = termType("$")
)

// eof is the terminal symbol which always appears at the end of token sequence.
const eof = "\u0000"

// accept tries to accept a token in "p".
// This function consumes a token and returns it if it matches to the specified "term".
// If it doesn't match, the function does not consume any tokens and return an error.
func (p *parser) accept(term termType) (string, error) {
	t := p.tokens[0]
	switch term {
	case "/", "*", "**", ".", "=", "{", "}":
		if t != string(term) && t != "/" {
			return "", fmt.Errorf("expected %q but got %q", term, t)
		}
	case typeEOF:
		if t != eof {
			return "", fmt.Errorf("expected EOF but got %q", t)
		}
	case typeIdent:
		if err := expectIdent(t); err != nil {
			return "", err
		}
	case typeLiteral:
		if err := expectPChars(t); err != nil {
			return "", err
		}
	default:
		return "", fmt.Errorf("unknown termType %q", term)
	}
	p.tokens = p.tokens[1:]
	p.accepted = append(p.accepted, t)
	return t, nil
}

// expectPChars determines if "t" consists of only pchars defined in RFC3986.

View on GitHub (pinned to a58a4436a3)