nsqio/nsq · error · http_api.Err
INVALID_ARG_TOPIC
INVALID_ARG_TOPIC
Error message
INVALID_ARG_TOPIC
What it means
After the topic parameter is present, GetTopicChannelArgs validates it with protocol.IsValidTopicName, which enforces the regex ^[.a-zA-Z0-9_-]+(#ephemeral)?$ plus a length of 1..64 characters. A value that fails (including an empty string) returns INVALID_ARG_TOPIC and the HTTP handler responds 400.
Source
Thrown at internal/http_api/topic_channel_args.go:20
import (
"errors"
"github.com/nsqio/nsq/internal/protocol"
)
type getter interface {
Get(key string) (string, error)
}
func GetTopicChannelArgs(rp getter) (string, string, error) {
topicName, err := rp.Get("topic")
if err != nil {
return "", "", errors.New("MISSING_ARG_TOPIC")
}
if !protocol.IsValidTopicName(topicName) {
return "", "", errors.New("INVALID_ARG_TOPIC")
}
channelName, err := rp.Get("channel")
if err != nil {
return "", "", errors.New("MISSING_ARG_CHANNEL")
}
if !protocol.IsValidChannelName(channelName) {
return "", "", errors.New("INVALID_ARG_CHANNEL")
}
return topicName, channelName, nil
}
View on GitHub (pinned to 85cf10c09c)
Solutions
- Use only letters, digits, dot, underscore, hyphen (optionally the #ephemeral suffix) and 1-64 chars, e.g. topic=orders.created
- Sanitize generated topic names at the publisher: replace invalid characters with '_' or '-' before the first publish.
- If the name came from URL decoding, verify it is non-empty after decode.
Example fix
# before curl -X POST 'http://127.0.0.1:4151/channel/create?topic=order/created&channel=ch' # after curl -X POST 'http://127.0.0.1:4151/channel/create?topic=order.created&channel=ch'
Defensive patterns
Strategy: validation
Validate before calling
var validTopicChannelNameRegex = regexp.MustCompile(`^[.a-zA-Z0-9_-]+(#ephemeral)?$`)
func isValidNSQName(name string) bool {
return len(name) >= 1 && len(name) <= 64 && validTopicChannelNameRegex.MatchString(name)
}
if !isValidNSQName(topic) {
return fmt.Errorf("invalid topic name %q", topic)
} Type guard
func isValidTopicName(name string) bool {
return len(name) >= 1 && len(name) <= 64 && validTopicChannelNameRegex.MatchString(name)
} Try / catch
if resp.StatusCode == 400 && strings.Contains(string(body), "INVALID_ARG_TOPIC") {
topic = sanitizeNSQName(topic) // replace [^.a-zA-Z0-9_-] with '_' , truncate to 64
// rebuild and retry once
} Prevention
- Sanitize topic names at the publisher before the first message; NSQ has no rename operation.
- Add unit tests asserting your topic generator only emits [.a-zA-Z0-9_-] and length <= 64.
When it happens
Trigger: Passing a topic containing spaces, slashes, unicode, or other characters outside [.a-zA-Z0-9_-], e.g. ?topic=order/events or ?topic=order queue; passing topic= (empty); passing a name longer than 64 characters. Note that topic#ephemeral IS allowed by the regex.
Common situations: Deriving topic names from user input, file paths, or free-form event types without sanitizing; splitting a topic on '/' and accidentally keeping the separator; names trimmed to nothing after URL decoding.
Related errors
- MISSING_ARG_TOPIC
- MISSING_ARG_CHANNEL
- INVALID_ARG_CHANNEL
- address should not contain scheme
- --nsqd-http-address or --lookupd-http-address required
AI-assisted analysis of nsqio/nsq@85cf10c09c (2026-08-16).
Data as JSON: /api/errors/706fc1395aa80da8.
Report an issue: GitHub.