gofiber/fiber · warning

sse: invalid event: %w

Error message

sse: invalid event: %w

What it means

writeEvent rejects an Event.Name (the SSE event field) containing CR or LF for the same wire-format reason as the id: a newline would terminate the field early. sanitizeField returns errInvalidField and the error is wrapped.

Source

Thrown at middleware/sse/event.go:53

	if err != nil {
		return err
	}

	var frame bytes.Buffer

	if event.ID != "" {
		id, err := sanitizeField(event.ID)
		if err != nil {
			return fmt.Errorf("sse: invalid id: %w", err)
		}
		if id != "" {
			appendField(&frame, "id", id)
		}
	}
	if event.Name != "" {
		name, err := sanitizeField(event.Name)
		if err != nil {
			return fmt.Errorf("sse: invalid event: %w", err)
		}
		if name != "" {
			appendField(&frame, "event", name)
		}
	}
	if event.Retry > 0 {
		appendField(&frame, "retry", utils.FormatInt(event.Retry.Milliseconds()))
	}
	if data.hasData {
		appendData(&frame, data.data)
	}
	frame.WriteByte('\n') //nolint:errcheck // bytes.Buffer writes never fail.
	if _, err := w.Write(frame.Bytes()); err != nil {
		return fmt.Errorf("sse: write event: %w", err)
	}
	return nil
}

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Restrict event names to a fixed set of single-line tokens (recommended SSE practice).
  2. Sanitize any dynamic name by removing/replacing CR and LF.

Example fix

// before
stream.Event(sse.Event{Name: topic, Data: msg}) // topic may contain \n

// after
name := strings.NewReplacer("\r\n", "", "\r", "", "\n", "").Replace(topic)
stream.Event(sse.Event{Name: name, Data: msg})
Defensive patterns

Strategy: validation

Validate before calling

const validEventName = `^[A-Za-z0-9_.-]+$`
var nameRe = regexp.MustCompile(validEventName)
func cleanEventName(s string) string {
    s = strings.NewReplacer("\r", "", "\n", "").Replace(s)
    if !nameRe.MatchString(s) { return "message" }
    return s
}

Try / catch

if err := stream.Event(ev); err != nil {
    log.Warnf("dropping event with invalid name: %v", err)
}

Prevention

When it happens

Trigger: Passing sse.Event{Name: "user\nupdate"} or any name containing embedded CR/LF - typically from concatenating lines or unsanitized input.

Common situations: Building event names from user/DB strings; whitespace/newline artifacts in config; multi-token names joined with newlines.

Related errors


AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04). Data as JSON: /data/errors/f926ee2ded57f97a.json. Report an issue: GitHub.