{"id":1239,"hash":"101436b225fa365156f809c09765bfcf72d90fdaf3552d3d2bdfd6c7e6d3b468","pattern":"Return custom error message from struct tag validation","full_message":"I'm using Go 1.17 with Gin and I want to implement a struct validation before sending the data to my database. I took the example from Gin documentation.\n\nIn the struct we can declare different tags to validate a field like this:\n\ntype User struct {\n    FirstName      string `json:\"first_name\" binding:\"required\"`\n    LastName       string `json:\"last_name\" binding:\"required\"`\n    Age            uint8  `json:\"age\" binding:\"gte=0,lte=130\"`\n    Email          string `json:\"email\" binding:\"required,email\"`\n    FavouriteColor string `json:\"favourite_color\" binding:\"iscolor\"`\n}\n\nAnd in the handler I can grab the error like this:\n\nvar u User\nif err := c.ShouldBindWith(&u, binding.Query); err == nil {\n    c.JSON(http.StatusOK, gin.H{\"message\": \"Good Job\"})\n} else {\n    c.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n}\n\nThe error message will be:\n\n{\n    \"error\": \"Key: 'User.FirstName' Error:Field validation for 'FirstName' failed on the 'required' tag\\nKey: 'User.LastName' Error:Field validation for 'LastName' failed on the 'required' tag\\nKey: 'User.Email' Error:Field validation for 'Email' failed on the 'required' tag\\nKey: 'User.FavouriteColor' Error:Field validation for 'FavouriteColor' failed on the 'iscolor' tag\"\n}\n\nThe error messages are too verbose how it's possible to returns a better error to the user? I'd like to model the json response like:\n\n{\n    \"errors\": [\n        \"first_name\": \"This field is required\",\n        \"last_name\": \"This field is required\",\n        \"age\": \"This field is required\",\n        \"email\": \"Invalid email\"\n    ]\n}","ecosystem":"go","package_name":"validation","package_version":null,"solution":"Gin gonic uses the package github.com/go-playground/validator/v10 to perform binding validation. If the validation fails, the error returned is a validator.ValidationErrors.\n\nThis is not mentioned explicitly but here in Model binding and validation it states:\n\nGin uses go-playground/validator/v10 for validation. Check the full docs on tags usage here.\n\nThat links to the go-playground/validator/v10 documentation, where you find the paragraph Validation Functions Return Type error.\n\nYou can use the standard errors package to check if the error is that, unwrap it, and access the single fields, which are validator.FieldError. From that, you can construct whatever error message you want.\n\nGiven an error model like this:\n\ntype ApiError struct {\n    Field string\n    Msg   string\n}\n\nYou can do this:\n\n    var u User\n    err := c.BindQuery(&u);\n    if err != nil {\n        var ve validator.ValidationErrors\n        if errors.As(err, &ve) {\n            out := make([]ApiError, len(ve))\n            for i, fe := range ve {\n                out[i] = ApiError{fe.Field(), msgForTag(fe.Tag())}\n            }\n            c.JSON(http.StatusBadRequest, gin.H{\"errors\": out})\n        }\n        return\n    }\n\nwith a helper function to output a custom error message for your validation rules:\n\nfunc msgForTag(tag string) string {\n    switch tag {\n    case \"required\":\n        return \"This field is required\"\n    case \"email\":\n        return \"Invalid email\"\n    }\n    return \"\"\n}\n\nIn my test, this outputs:\n\n{\n    \"errors\": [\n        {\n            \"Field\": \"Number\",\n            \"Msg\": \"This field is required\"\n        }\n    ]\n}\n\nPS: To have a json output with dynamic keys, you can use map[string]string instead of a fixed struct model.","confidence":0.95,"source":"stackoverflow","source_url":"https://stackoverflow.com/questions/70069834/return-custom-error-message-from-struct-tag-validation","votes":14,"created_at":"2026-04-19T04:52:41.404843+00:00","updated_at":"2026-04-19T04:52:41.404843+00:00"}