gofr-dev/gofr · error
failed to set key-value pair: %w
Error message
failed to set key-value pair: %w
What it means
NATS KV Set wraps failures from c.kv.Put with 'failed to set key-value pair: %w', preserving the JetStream cause. It means the write to the bucket failed — typically a connection, bucket-existence, or JetStream limits problem — rather than a data issue.
Source
Thrown at pkg/gofr/datasource/kv-store/nats/nats.go:131
entry, err := c.kv.Get(key)
if err != nil {
if errors.Is(err, nats.ErrKeyNotFound) {
return "", fmt.Errorf("%w: %s", errKeyNotFound, key)
}
return "", fmt.Errorf("failed to get key: %w", err)
}
return string(entry.Value()), nil
}
func (c *Client) Set(ctx context.Context, key, value string) error {
span := c.addTrace(ctx, "set", key)
defer c.sendOperationStats(time.Now(), "SET", "set", span, key, value)
_, err := c.kv.Put(key, []byte(value))
if err != nil {
return fmt.Errorf("failed to set key-value pair: %w", err)
}
return nil
}
func (c *Client) Delete(ctx context.Context, key string) error {
span := c.addTrace(ctx, "delete", key)
defer c.sendOperationStats(time.Now(), "DELETE", "delete", span, key)
err := c.kv.Delete(key)
if err != nil {
if errors.Is(err, nats.ErrKeyNotFound) {
return fmt.Errorf("%w: %s", errKeyNotFound, key)
}
return fmt.Errorf("failed to delete key: %w", err)
}
View on GitHub (pinned to 187eb24962)
Solutions
- Read the wrapped cause to distinguish connection vs bucket vs size errors
- Ensure the bucket exists at startup (Create the KV bucket before use) and reconnect logic is in place
- Reduce value size or raise server max_payload if large values are intended
- Retry with backoff on transient connection errors
Example fix
// before
err := store.Set(ctx, key, bigBlob)
// after
if len(bigBlob) > maxPayload { return ErrValueTooLarge }
if err := store.Set(ctx, key, bigBlob); err != nil {
return retry.WithBackoff(func() error { return store.Set(ctx, key, bigBlob) })
} Defensive patterns
Strategy: retry
Validate before calling
// pre-flight checks before Set
if len(value) > maxJetstreamPayload { return fmt.Errorf("value too large: %d bytes", len(value)) }
if _, err := js.KeyValue(cfg.Bucket); err != nil { return fmt.Errorf("bucket %q missing: %w", cfg.Bucket, err) } Type guard
func isSetFailure(err error) bool { return err != nil && strings.Contains(err.Error(), "failed to set key-value pair") } // prefer keeping the raw error and errors.Unwrap Try / catch
if err := store.Set(ctx, key, value); err != nil {
if isTransient(errors.Unwrap(err)) {
return retry.WithBackoff(func() error { return store.Set(ctx, key, value) })
}
return err
} Prevention
- Create the KV bucket at startup and verify it before writes
- Enforce a max value size below the server's max_payload
- Enable NATS reconnect options and idempotent writes (Set is an upsert)
- Check server disk/JetStream limits if writes fail persistently
When it happens
Trigger: c.kv.Put(key, []byte(value)) errors: bucket does not exist, NATS connection lost, JetStream publish fails due to max payload/message-size limits, no storage resources, or account lacks publish permission.
Common situations: Bucket deleted or never created, oversized values exceeding JetStream max payload, NATS server restart, closed/expired connection, disk-full on the server's file store.
Related errors
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/808a22e57547138d.
Report an issue: GitHub.