{"record":{"id":"4c0d347744779ee3","repo":"nats-io/nats-server","slug":"stream-metadata-exceeds-maximum-size-of-d-bytes","errorCode":null,"errorMessage":"stream metadata exceeds maximum size of %d bytes","messagePattern":"stream metadata exceeds maximum size of (.+?) bytes","errorType":"error_code","errorClass":"JSStreamInvalidConfigError","httpStatus":null,"severity":"error","filePath":"server/stream.go","lineNumber":1888,"sourceCode":"\tif config == nil {\n\t\treturn StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf(\"stream configuration invalid\"))\n\t}\n\tif !isValidAssetName(config.Name) {\n\t\treturn StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf(\"stream name is required and can not contain '.', '*', '>', '\\\\', '/'\"))\n\t}\n\tif len(config.Name) > JSMaxNameLen {\n\t\treturn StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf(\"stream name is too long, maximum allowed is %d\", JSMaxNameLen))\n\t}\n\tif len(config.Description) > JSMaxDescriptionLen {\n\t\treturn StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf(\"stream description is too long, maximum allowed is %d\", JSMaxDescriptionLen))\n\t}\n\n\tvar metadataLen int\n\tfor k, v := range config.Metadata {\n\t\tmetadataLen += len(k) + len(v)\n\t}\n\tif metadataLen > JSMaxMetadataLen {\n\t\treturn StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf(\"stream metadata exceeds maximum size of %d bytes\", JSMaxMetadataLen))\n\t}\n\n\tcfg := *config\n\n\tif _, err := cfg.Retention.MarshalJSON(); err != nil {\n\t\treturn cfg, NewJSStreamInvalidConfigError(fmt.Errorf(\"invalid retention\"))\n\t}\n\tif _, err := cfg.Discard.MarshalJSON(); err != nil {\n\t\treturn cfg, NewJSStreamInvalidConfigError(fmt.Errorf(\"invalid discard policy\"))\n\t}\n\tif _, err := cfg.Compression.MarshalJSON(); err != nil {\n\t\treturn cfg, NewJSStreamInvalidConfigError(fmt.Errorf(\"invalid compression\"))\n\t}\n\n\t// Make file the default.\n\tif cfg.Storage == 0 {\n\t\tcfg.Storage = FileStorage\n\t}","sourceCodeStart":1870,"sourceCodeEnd":1906,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/stream.go#L1870-L1906","documentation":"The combined length of all keys and values in StreamConfig.Metadata exceeds JSMaxMetadataLen (128 KiB, 131072 bytes). The server sums len(k)+len(v) across the map and rejects configs over this budget to bound config size.","triggerScenarios":"Creating/updating a stream with a Metadata map whose total key+value bytes exceed 131072; attaching large JSON documents, traces, or template-generated metadata to the stream.","commonSituations":"Sync tools that copy entire resource tags into stream metadata; CI injecting verbose labels; aggregating per-tenant metadata into one stream's map.","solutions":["Reduce metadata size: shorten keys and values, drop unneeded entries.","Move large blobs out of metadata into an external store and keep a reference.","Compute total size client-side (sum of len(k)+len(v)) and enforce <= 131072 before the API call.","Apply the same budget to consumer metadata, which shares the same limit."],"exampleFix":"// before\nmd := map[string]string{\"doc\": largeJSON} // > 128 KiB\njs.CreateStream(ctx, jetstream.StreamConfig{Name: \"ORDERS\", Metadata: md})\n// after\nmd := map[string]string{\"docRef\": \"s3://bucket/doc.json\"}\njs.CreateStream(ctx, jetstream.StreamConfig{Name: \"ORDERS\", Metadata: md})","handlingStrategy":"validation","validationCode":"func validMetadata(md map[string]string) error {\n  var n int\n  for k, v := range md { n += len(k) + len(v) }\n  if n > 128*1024 {\n    return fmt.Errorf(\"metadata too large: %d > %d bytes\", n, 128*1024)\n  }\n  return nil\n}","typeGuard":"func metadataFits(md map[string]string) bool {\n  n := 0\n  for k, v := range md { n += len(k) + len(v) }\n  return n <= 128*1024\n}","tryCatchPattern":null,"preventionTips":["Measure total key+value bytes before submitting metadata.","Keep large payloads out of metadata; store references instead.","Trim keys as well as values — both count toward the limit.","Re-check limits after any templated/config-driven metadata injection."],"tags":["jetstream","stream-config","metadata","size-limit"],"backgroundTag":"stream-metadata-size-exceeded","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}