t8y2/dbx · error

decode ACL list: %w

Error message

decode ACL list: %w

What it means

listACLs in the RocketMQ driver decodes the admin HTTP response into either a plain array of ACLs or a wrapper object {"acls": [...]}. When the body starts with '[' but is not a valid JSON array of ACLs, json.Unmarshal fails and the error is wrapped as 'decode ACL list: <cause>'.

Source

Thrown at agents/drivers/rocketmq/acl.go:54

	defer cancel()
	address, err := a.brokerAddressForName(stringValue(params, "brokerName"))
	if err != nil {
		return nil, err
	}
	response, err := invokeRemotingWithClient(ctx, address, remoting.NewRequest(remoting.ListAcl, map[string]string{
		"subjectFilter":  strings.TrimPrefix(stringValue(params, "principal", "subject"), "User:"),
		"resourceFilter": stringValue(params, "resourceName"),
	}))
	if err != nil {
		return nil, err
	}
	var wrapper struct {
		Acls []aclWire `json:"acls"`
	}
	body := repairRocketMQJSON(response.Body)
	if len(body) > 0 && body[0] == '[' {
		if err := json.Unmarshal(body, &wrapper.Acls); err != nil {
			return nil, fmt.Errorf("decode ACL list: %w", err)
		}
	} else if err := json.Unmarshal(body, &wrapper); err != nil {
		return nil, fmt.Errorf("decode ACL list: %w", err)
	}
	principalFilter := strings.TrimPrefix(stringValue(params, "principal", "subject"), "User:")
	resourceFilter := stringValue(params, "resourceName")
	rows := make([]map[string]any, 0)
	for _, acl := range wrapper.Acls {
		if principalFilter != "" && acl.Subject != principalFilter && acl.Subject != "User:"+principalFilter {
			continue
		}
		for _, policy := range acl.Policies {
			for _, entry := range policy.Entries {
				if resourceFilter != "" && entry.Resource != resourceFilter {
					continue
				}
				actions := entry.Actions
				if len(actions) == 0 {

View on GitHub (pinned to c0390bff16)

Solutions

  1. Log/curl the raw response body from the ACL list endpoint to see what is actually returned
  2. Run the body through repairRocketMQJSON-aware handling and confirm it is valid JSON (validate with jq)
  3. Upgrade or align the RocketMQ server version so its ACL JSON matches aclWire field types
  4. Inspect the wrapped cause (%w) for the exact JSON error, e.g. a type mismatch identifying the offending field

Example fix

// before
body, _ := io.ReadAll(resp.Body) // may be truncated/error page
acl, err := listACLs(body)
// after
if !json.Valid(body) {
    return fmt.Errorf("ACL endpoint returned invalid JSON: %q", string(body))
}
if err := json.Unmarshal(body, &acls); err != nil {
    return fmt.Errorf("decode ACL list: %w (body head: %.200s)", err, string(body))
}
Defensive patterns

Strategy: try-catch

Validate before calling

if !json.Valid(body) {
    return fmt.Errorf("ACL list response is not valid JSON")
}
if len(body) > 0 && body[0] == '[' {
    var probe []map[string]any
    if json.Unmarshal(body, &probe) != nil {
        return fmt.Errorf("ACL array decode failed; inspect body: %.200s", string(body))
    }
}

Try / catch

acls, err := listACLs(params)
if err != nil {
    var decErr *json.UnmarshalTypeError
    if errors.As(err, &decErr) {
        log.Printf("ACL schema drift at %v: %v", decErr.Field, decErr)
    }
    return err
}

Prevention

When it happens

Trigger: The RocketMQ admin endpoint returned a bracket-leading body that fails to unmarshal into []aclWire — e.g. truncated JSON, a '[object Object]'-style error string, or fields with incompatible types.

Common situations: RocketMQ proxy/version returning a different wire format, an auth/error page slipping through with bracket-leading text, network truncation of the response body, schema drift between aclWire and the server's ACL JSON.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/6e84e54939ad5057. Report an issue: GitHub.