Don't call your fields in a handler module "handler"

I’m building a simple kubernetes admission webhook with Caddy for demonstration purposes.

I registered a new HTTP handler.

Now, I made the mistake of calling one of the fields in my module “handler” as well.

Here is the code: caddy-k8s-admission/admission.go at c24ab36932c9afe1b601b841fa10943e114e14c5 · sagikazarmark/caddy-k8s-admission · GitHub

After that Caddy was throwing a me all kinds of errors as I’ve been trying to debug it.

Finally, after a hunch I renamed it to something gibberish and it started to work.

I have no idea if this is documented somewhere or not. I couldn’t find any indication.

I just thought I’d throw it out there, maybe someone else stumbles upon the same problem.

That’s odd and shouldn’t be the case. Can you share more what those errors were? Pretty sure we have a couple of modules that have field called Handler. The code also isn’t sensitive to the field name.

3 Likes

What were the errors?

1 Like
{“level”:“error”,“ts”:1755221298.395492,“logger”:“admin.api”,“msg”:“request error”,“error”:“loading config: loading new config: loading http app module: provision http: server srv0: setting up route handlers: route 0: loading handler modules: position 0: loading module ‘subroute’: provision http.handlers.subroute: setting up subroutes: route 0: loading handler modules: position 0: loading module ‘subroute’: provision http.handlers.subroute: setting up subroutes: route 0: loading handler modules: position 0: loading module ‘k8s_admission’: provision http.handlers.k8s_admission: admission controller is required”,“status_code”:400}

The error can be reproduced on this branch: Rename stuff back to handler to demonstrate errors by sagikazarmark · Pull Request #5 · sagikazarmark/caddy-k8s-admission · GitHub

I renamed “controller” back to “handler”.

It’s actually a validation error, but it looks like even though the field is set, something overwrites it.

At some point, I looked at the JSON config and it looked like http handler modules actually have a handler property that overwrites whatever I put in there.

I looked at the code and found this: caddy/modules/caddyhttp/routes.go at master · caddyserver/caddy · GitHub

In any case, it’s entirely possible that I missed something, but renaming the field from handler solved my problem after I wasted a day on debugging, so I left it there.

So the problem is not the struct field itself, rather the name of the json field itself. Adapted handlers always have this form when adapted to JSON:

{

    "handler": "k8s_admission"

}

The json tag on the struct field is handler:

HandlerRaw json.RawMessage `json:"handler,omitempty" caddy:"namespace=k8s.admission inline_key=handler_type"`

Effectively, the marshaling ends up trying to produce this JSON:

{
    "handler": "k8s_admission",
    "handler": {
        "handler_type": "<controller_module>"
    }
}

That’s not valid JSON. What ends up happening is the adapter takes the last value set on the JSON field, which is k8s_admission, and making it the final value of the json field handler.

You can resolve it by changing the name of the JSON tag as such:

HandlerRaw json.RawMessage `json:"controller,omitempty" caddy:"namespace=k8s.admission inline_key=handler_type"`

keeping the struct field name intact.

2 Likes

Thanks for the clarification. That’s what I figured.

I don’t think it makes much of a difference, though: if you have a field name “handler” in a struct, I’m pretty sure everyone’s first instinct would be to name the JSON field the same.

So I think the warning still stands, especially because the error is not obvious and it took some time to figure this out.

For those who are not familiar with how the http handler config looks like in JSON (like myself), a warning in the documentation would save time IMO

Fair enough. We can probably have a statement about that on this page of the docs:

If any of the readers/followers is interested, here’s the website repository. Feel free to send a PR.

2 Likes

This topic was automatically closed after 30 days. New replies are no longer allowed.