gofiber/fiber · warning

sse: invalid event

Error message

sse: invalid event: %w

What it means

Thrown by writeEvent when sanitizeField rejects the Event.Name (the SSE 'event' field / custom event type) because it contains a CR or LF. Same wire-format protection as error 206, applied to the event name instead of the id.

Solutions

  1. Restrict event names to single-line tokens (letters, digits, '-', '_', '.').
  2. Sanitize/whitelist the name before assigning it to Event.Name.
  3. Use a fixed vocabulary of event names rather than free-form input.

Example fix

// before
stream.Event(sse.Event{Name: topicFromUser, Data: payload})

// after
name := strings.Map(func(r rune) rune {
    if r == '\n' || r == '\r' { return -1 }
    return r
}, topicFromUser)
stream.Event(sse.Event{Name: name, Data: payload})
Defensive patterns

Strategy: validation

Validate before calling

func safeSSEName(name string) string {
    return strings.Map(func(r rune) rune {
        if r == '\n' || r == '\r' { return -1 }
        return r
    }, name)
}

Type guard

func isValidSSEEventName(s string) bool {
    if s == "" { return false }
    for _, r := range s {
        if r == '\n' || r == '\r' { return false }
    }
    return true
}

Try / catch

if !isValidSSEEventName(name) {
    name = "message" // safe default
}
stream.Event(sse.Event{Name: name, Data: payload})

Prevention

When it happens

Trigger: Setting Event.Name to a value containing a newline or carriage return — e.g. building the event name from user input that was not sanitized, or from a multi-line template.

Common situations: Dynamic event names derived from message topics, log lines, or user input that happen to contain newlines; copy-paste introducing stray \n.

Related errors


AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11). Data as JSON: /api/errors/f926ee2ded57f97a. Report an issue: GitHub.

Appendix: 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 a105acad6c)