valyala/fasthttp · error

malformed mime header: missing colon: %q

Error message

malformed mime header: missing colon: %q

What it means

readContinuedLineSlice in the header scanner requires every header line to contain a colon separating key from value; a non-empty line without any colon is not a valid MIME header line and aborts scanning with this error.

Source

Thrown at headerscanner.go:121

	}
	return line
}

// readContinuedLineSlice reads continued lines from b until it finds a line
// that does not start with a space or tab, or it reaches the end of b.
// It also returns the position of the first colon in the returned line:
// the line can never start with a space or tab (the scanner rejects that for
// the first line and joins such lines into the previous header), so trimming
// it doesn't shift the colon.
func (s *headerScanner) readContinuedLineSlice() ([]byte, int, error) {
	line := s.readLine()
	if len(line) == 0 { // blank line - no continuation
		return line, -1, nil
	}

	colon := bytes.IndexByte(line, ':')
	if colon < 0 {
		return nil, -1, fmt.Errorf("malformed mime header: missing colon: %q", line)
	}

	// If the next line doesn't start with a space or tab, we are done.
	if len(s.b)-s.r > 1 {
		peek := s.b[s.r : s.r+2]
		if len(peek) > 0 && (isASCIILetter(peek[0]) || peek[0] == '\n') ||
			len(peek) == 2 && peek[0] == '\r' && peek[1] == '\n' {
			return trim(line), colon, nil
		}
	}

	mline := trim(line)

	// Read continuation lines.
	for s.skipSpace() {
		mline = append(mline, ' ')
		line := s.readLine()
		mline = append(mline, trim(line)...)

View on GitHub (pinned to c96f600972)

Solutions

  1. Fix Content-Length or chunked framing so body bytes are not parsed as headers.
  2. Ensure every header line contains 'key: value' with a colon.
  3. Check for premature request pipelining or stream desynchronization in your client.
  4. Log the offending line (%q in the error) to identify the corrupted part of the stream.

Example fix

// before (raw write missing colon)
c.Write([]byte("justtext\r\n\r\n"))
// after
c.Write([]byte("X-Note: justtext\r\n\r\n"))
Defensive patterns

Strategy: validation

Validate before calling

func lineHasColon(line []byte) bool { return bytes.IndexByte(line, ':') >= 0 }
// validate every raw header line before writing it to the wire

Try / catch

if err := scanner step err; err != nil && strings.Contains(err.Error(), "missing colon") {
    // framing is desynchronized: close connection, do not attempt recovery
}

Prevention

When it happens

Trigger: A header block line like 'garbageline\r\n' with no colon, e.g. leftover body bytes interpreted as headers, a truncated request, or continuation lines without a base 'key:' line.

Common situations: Pipelined/partial writes corrupting the header/body boundary; requests where the body starts before headers ended (wrong Content-Length); fuzzing or scanner traffic.

Understand the failure class

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/6621ebb15957ecdd. Report an issue: GitHub.