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
- Restrict event names to a fixed set of single-line tokens (recommended SSE practice).
- 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
- Use a closed set of event names (e.g. 'message','update').
- Sanitize any dynamic name to remove CR/LF.
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
- sse: invalid id: %w
- log: context tag name and function are required
- field must not contain CR or LF
- sse: write event: %w
- sse: write heartbeat: %w
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/f926ee2ded57f97a.json.
Report an issue: GitHub.