Skip to content

[Bug] v2.3.0 gin contrib breaks builds with -tags nomsgpack #4114

@sdotson

Description

@sdotson

Description

The gin contrib package in dd-trace-go v2.3.0 fails to compile when building with the -tags nomsgpack build tag.

Environment

  • dd-trace-go version: v2.3.0
  • Go version: 1.24.0
  • Affected package: github.com/DataDog/dd-trace-go/contrib/gin-gonic/gin/v2

Steps to Reproduce

  1. Create a Go project that imports github.com/DataDog/dd-trace-go/contrib/gin-gonic/gin/v2
  2. Build with the nomsgpack tag:
    go build -tags nomsgpack ./...

Expected Behavior

The build should succeed. The gin framework supports the nomsgpack build tag to exclude msgpack support and reduce binary size by removing the heavy github.com/ugorji/go/codec dependency.

Actual Behavior

Build fails with compilation error:

# github.com/DataDog/dd-trace-go/contrib/gin-gonic/gin/v2
../../go/pkg/mod/github.com/!data!dog/dd-trace-go/contrib/gin-gonic/gin/[email protected]/appsec.go:54:17: cannot use AppsecBinding{…} (value of struct type AppsecBinding) as binding.jsonBinding value in assignment
../../go/pkg/mod/github.com/!data!dog/dd-trace-go/contrib/gin-gonic/gin/[email protected]/appsec.go:55:16: cannot use AppsecBinding{…} (value of struct type AppsecBinding) as binding.xmlBinding value in assignment
../../go/pkg/mod/github.com/!data!dog/dd-trace-go/contrib/gin-gonic/gin/[email protected]/appsec.go:56:21: cannot use AppsecBinding{…} (value of struct type AppsecBinding) as binding.protobufBinding value in assignment
../../go/pkg/mod/github.com/!data!dog/dd-trace-go/contrib/gin-gonic/gin/[email protected]/appsec.go:57:10: undefined: binding.MsgPack
../../go/pkg/mod/github.com/!data!dog/dd-trace-go/contrib/gin-gonic/gin/[email protected]/appsec.go:58:17: cannot use AppsecBinding{…} (value of struct type AppsecBinding) as binding.yamlBinding value in assignment
../../go/pkg/mod/github.com/!data!dog/dd-trace-go/contrib/gin-gonic/gin/[email protected]/appsec.go:59:17: cannot use AppsecBinding{…} (value of struct type AppsecBinding) as binding.tomlBinding value in assignment

Root Cause

The issue was introduced in v2.3.0 with the AppSec request body analysis feature (#3930). The appsec.go file unconditionally references binding.MsgPack in its init() function:

https://github.com/DataDog/dd-trace-go/blob/main/contrib/gin-gonic/gin/appsec.go#L51-L59

func init() {
    binding.JSON = AppsecBinding{BindingBody: binding.JSON}
    binding.XML = AppsecBinding{BindingBody: binding.XML}
    binding.ProtoBuf = AppsecBinding{BindingBody: binding.ProtoBuf}
    binding.MsgPack = AppsecBinding{BindingBody: binding.MsgPack}  // Line 57 - undefined when nomsgpack tag is used
    binding.YAML = AppsecBinding{BindingBody: binding.YAML}
    binding.TOML = AppsecBinding{BindingBody: binding.TOML}
}

When the nomsgpack build tag is active, gin's binding package doesn't define binding.MsgPack (see gin's binding_nomsgpack.go), causing the compilation error.

Proposed Solution

Add build tag guards to handle the msgpack binding conditionally. Here's a suggested approach:

appsec.go (default, with msgpack):

//go:build !nomsgpack

func init() {
    binding.JSON = AppsecBinding{BindingBody: binding.JSON}
    binding.XML = AppsecBinding{BindingBody: binding.XML}
    binding.ProtoBuf = AppsecBinding{BindingBody: binding.ProtoBuf}
    binding.MsgPack = AppsecBinding{BindingBody: binding.MsgPack}
    binding.YAML = AppsecBinding{BindingBody: binding.YAML}
    binding.TOML = AppsecBinding{BindingBody: binding.TOML}
}

appsec_nomsgpack.go (new file, without msgpack):

//go:build nomsgpack

func init() {
    binding.JSON = AppsecBinding{BindingBody: binding.JSON}
    binding.XML = AppsecBinding{BindingBody: binding.XML}
    binding.ProtoBuf = AppsecBinding{BindingBody: binding.ProtoBuf}
    // binding.MsgPack is not available with nomsgpack tag
    binding.YAML = AppsecBinding{BindingBody: binding.YAML}
    binding.TOML = AppsecBinding{BindingBody: binding.TOML}
}

Workaround

Until this is fixed, users can pin to v2.2.3 using replace directives in their go.mod:

replace (
    github.com/DataDog/dd-trace-go/contrib/gin-gonic/gin/v2 => github.com/DataDog/dd-trace-go/contrib/gin-gonic/gin/v2 v2.2.3
    github.com/DataDog/dd-trace-go/contrib/net/http/v2 => github.com/DataDog/dd-trace-go/contrib/net/http/v2 v2.2.3
    github.com/DataDog/dd-trace-go/v2 => github.com/DataDog/dd-trace-go/v2 v2.2.3
)

Impact

This affects any project using both:

  • dd-trace-go v2.3.0+ with gin contrib
  • The nomsgpack build tag (either explicitly or through dependencies)

This is a regression from v2.2.3, which builds successfully with the nomsgpack tag.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions