go-playground/validator
:100:Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving
Healthy across the board
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 1w ago
- ✓52+ active contributors
- ✓Distributed ownership (top contributor 25% of recent commits)
Show 3 more →Show less
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/go-playground/validator)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/go-playground/validator on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: go-playground/validator
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/go-playground/validator shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 1w ago
- 52+ active contributors
- Distributed ownership (top contributor 25% of recent commits)
- MIT licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live go-playground/validator
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/go-playground/validator.
What it runs against: a local clone of go-playground/validator — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in go-playground/validator | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | Last commit ≤ 40 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of go-playground/validator. If you don't
# have one yet, run these first:
#
# git clone https://github.com/go-playground/validator.git
# cd validator
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of go-playground/validator and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "go-playground/validator(\\.git)?\\b" \\
&& ok "origin remote is go-playground/validator" \\
|| miss "origin remote is not go-playground/validator (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 40 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~10d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/go-playground/validator"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
go-playground/validator is a production-grade Go struct and field validation library that implements declarative validation rules via struct tags (e.g., validate:"required,email"). It supports cross-field validation, nested struct diving, map/slice/array traversal, and custom validators—solving the common problem of repetitive manual validation logic in Go services. Single-package library with baked_in.go containing ~100+ validator implementations (required, email, min, max, etc.), cache.go for performance optimization, field_level.go for cross-field validation context, and errors.go for ValidationErrors type. Examples in _examples/ demonstrate each pattern (custom, dive, struct-level, map-validation, translations). Non-standard/ contains optional language/currency/country validators.
👥Who it's for
Go backend developers building REST APIs, microservices, or CLI tools who need to validate incoming request bodies, configuration structs, or domain models without writing hundreds of if/error checks. Also framework maintainers (notably Gin web framework) who integrate validator as a dependency for request binding.
🌱Maturity & risk
Highly mature and production-ready. The repo shows active maintenance (multiple recent commits, v10 release with breaking changes managed carefully), comprehensive test coverage via benchmarks_test.go, CI/CD pipeline in .github/workflows/workflow.yml, and is the de-facto validation library for Go (used by Gin framework). Some maintainer capacity concerns noted in discussions/1330.
Low-to-moderate risk. Single maintainer risk is explicitly called out in MAINTAINERS.md and discussions/1330 (actively seeking co-maintainers). Dependency surface is minimal (gabriel-vasile/mimetype, locales, leodido/go-urn, golang.org/* standard crypto/net libraries). No obvious red flags on breaking changes—v10 has clear upgrade guides (_examples/gin-upgrading-overriding/v8_to_v9.go). Main risk is maintainer burnout rather than technical debt.
Active areas of work
Active v10 maintenance with recent dependency updates (go1.24.4 toolchain), no visible breaking changes pending. Call for maintainers (discussions/1330) suggests focus on sustainability. GitHub Actions workflow runs on commits. Translation and i18n features appear actively used based on examples/translations and HTTP translation examples.
🚀Get running
git clone https://github.com/go-playground/validator.git
cd validator
go mod download
go test ./...
# Run a specific example:
cd _examples/simple
go run main.go
Daily commands:
No server to run. This is a library. Import and use in your code: import "github.com/go-playground/validator/v10" then v := validator.New(); err := v.Struct(myStruct). Run examples with cd _examples/<example-name> && go run main.go. Run tests with make test (see Makefile).
🗺️Map of the codebase
- baked_in.go: Contains all built-in validator implementations (100+ functions); this is where most new validation rules are added
- field_level.go: Defines the FieldLevel interface used in all validator functions; critical for understanding how validators access field values and metadata
- errors.go: Defines ValidationErrors type and FieldError interface; needed to understand how validation failures are reported to users
- cache.go: Performance optimization layer that caches compiled validator rules per struct type; important for understanding why the library is fast
- _examples/custom-validation/main.go: Demonstrates how to register and use custom validator functions; essential reference for extending validator with domain-specific rules
- _examples/struct-level/main.go: Shows cross-struct and cross-field validation patterns; needed to understand validation beyond individual field rules
- _examples/dive/main.go: Demonstrates the dive feature for validating nested slices, arrays, and maps; critical feature for complex data structures
- doc.go: Package-level documentation listing all validator tags (required, email, min, max, etc.); reference for available built-in validators
🛠️How to make changes
Adding a validator: implement function in baked_in.go following the func(fl FieldLevel) bool signature, register in registerDefaultValidators(). Cross-field logic: modify field_level.go to extend FieldLevel interface. Error messages: update language packs under non-standard/ or create new translation. Custom type support: extend the type assertion chain in field_level.go. Start by studying _examples/custom-validation/main.go and _examples/struct-level/main.go.
🪤Traps & gotchas
Tag parsing is strict: validator tags are case-sensitive and parsed left-to-right; validate:"required ,email" (with space) may not parse correctly. Interface{} handling: when validating interface{} fields, the library inspects the runtime type; nil interfaces won't validate as expected. Concurrent validator use: the global validator instance should be created once and reused; creating new validators per-request causes cache misses and performance degradation. Cross-field validation context: struct-level validators receive a FieldLevel with access to parent struct fields via Top() and Parent() methods, but this is easy to misuse. Custom types with Valuer: if your struct implements sql.driver.Valuer, the library will call Value() at validation time—ensure this doesn't have side effects.
💡Concepts to learn
- Struct Tag Reflection — Validator parses struct field tags at runtime using Go's reflect package to dynamically discover validation rules; understanding this is essential to knowing why the library works and its performance characteristics
- Cross-Field Validation — Core feature allowing validation rules that compare multiple fields (e.g.,
validate:"eqfield=Password"for password confirmation); requires understanding FieldLevel.GetData() and FieldLevel.Top() - Dive (Recursive Descent) — Allows validation of nested slices, arrays, and maps using the
divekeyword (e.g.,validate:"dive,required,email"); critical for validating complex data structures like lists of user objects - Interface{} Type Unwrapping — Validator uses reflection to inspect the runtime type of interface{} fields before validation, allowing it to handle generic types correctly
- Valuer Interface (database/sql/driver) — Validator automatically detects and calls the Value() method on fields implementing sql.driver.Valuer, enabling validation of database-specific types like sql.NullString
- Validator Rule Caching — The library caches compiled validator rules per struct type in cache.go to avoid re-parsing tags on every validation call; understanding this explains why creating multiple validator instances is inefficient
- Struct-Level Custom Validators — Allows writing custom validation logic that runs after field-level validation and can access the entire struct context; enables complex business rule validation impossible with tags alone
🔗Related repos
asaskevich/govalidator— Alternative Go validation library using functional approach; compare for differences in API design and when to use eachgo-ozzo/ozzo-validation— Another Go validation library with fluent API and custom rules; useful comparison for different validation paradigm (chainable vs. tag-based)gin-gonic/gin— Primary downstream consumer; Gin uses go-playground/validator as its default validation engine for request bindinggo-playground/locales— Direct dependency providing i18n support; validator uses this for multi-language error messagesgo-playground/universal-translator— Direct dependency that bridges validators with locale translations; required for error message internationalization
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive benchmarks for cross-field and cross-struct validation
The repo has benchmarks_test.go but it likely lacks coverage for the advertised cross-field and cross-struct validation features. This would help contributors and users understand performance characteristics of these complex validation scenarios, and provide a baseline for optimization work.
- [ ] Review existing benchmarks_test.go to identify gaps in cross-field/cross-struct scenarios
- [ ] Create benchmark cases for nested struct validation with dive tags
- [ ] Add benchmarks for map and slice validation with dive operators
- [ ] Run benchmarks against current main branch and document results in PR
- [ ] Compare performance between flat vs deeply nested struct validation
Add non-standard validators to main test suite and documentation
The non-standard/validators directory exists with notblank validator but lacks integration with the main test suite and README examples. This orphaned code should either be documented, integrated properly, or the pattern established for contributing custom validators. Currently it's unclear if this is a template or unmaintained code.
- [ ] Review non-standard/validators/notblank.go and notblank_test.go for quality and coverage
- [ ] Add integration tests in main test suite (e.g., validators_test.go) to validate non-standard validators work with main validator
- [ ] Create a _examples/non-standard-validators/main.go example showing how to use custom validators
- [ ] Update README.md with a section explaining the non-standard validators pattern and how to contribute custom validators
- [ ] Add CI step in .github/workflows/workflow.yml to run non-standard validator tests
Expand translation test coverage and add missing language validation examples
The translations directory has ar, de, and en but translations_test.go likely has gaps. Additionally, the _examples/translations/main.go could demonstrate more real-world scenarios. This would improve internationalization support and provide better user guidance.
- [ ] Review translations/*_test.go files to identify missing edge cases (e.g., plural forms, contextual messages)
- [ ] Add validation error translation tests for all advertised validators (url, email, required, min, max, etc.)
- [ ] Expand _examples/translations/main.go to show: (1) loading multiple language translations, (2) switching locales at runtime, (3) custom field name translations
- [ ] Add integration test demonstrating custom validator error message translation
- [ ] Document translation contribution process in CONTRIBUTING.md with examples for adding new language support
🌿Good first issues
- Add missing test coverage for the currency_codes.go, language_codes.go, and country_codes.go files—these validators exist but have no visible test files in the repo. Write parameterized tests in a new non-standard/validators_test.go matching the pattern in benchmarks_test.go.
- Create a new example in _examples/custom-error-messages/ demonstrating how to override error messages for built-in validators (e.g., changing 'required' to 'this field is mandatory' in different languages)—currently only translations/ example exists.
- Improve documentation in doc.go or add a PATTERNS.md guide explaining the difference between field-level validators (validate:"required"), cross-field validators (validate:"eqfield=OtherField"), and struct-level custom validators with concrete before/after code examples from the _examples/ directory.
⭐Top contributors
Click to expand
Top contributors
- @dependabot[bot] — 25 commits
- @nodivbyzero — 13 commits
- @deankarn — 4 commits
- @ahmedkamalio — 3 commits
- @shindonghwi — 3 commits
📝Recent commits
Click to expand
Recent commits
7c334e5— fix: reject hostnames with trailing hyphen in RFC 952 validator (#1569) (ahmedkamalio)6bcb7bc— feat: add origin validator for web origin URLs (#1565) (ahmedkamalio)6fd2fa8— docs: fix typos (#1568) (rymiyamoto)6d1d091— docs: use errors.As in README and translations example (#1563) (eyupcanakman)ee971fb— feat(translations): add timezone support for en and ja locales (#1566) (dedyf5)1c6cd04— Refactored out detectFileMIMEType, matchesMIMEType logic for reuse. Added standalone isMIMEType validator for flexibilit (dapzthelegend)3c25f1d— Reduce build size with dead code elimination (#1542) (zemzale)2f484d2— Add CLAUDE.md with repo guidance for Claude Code (#1564) (deankarn)ad3e048— chore(deps): bump golang.org/x/crypto from 0.49.0 to 0.50.0 (#1559) (dependabot[bot])06ef944— chore(deps): bump golang.org/x/text from 0.35.0 to 0.36.0 (#1558) (dependabot[bot])
🔒Security observations
The go-playground/validator codebase is generally well-structured as a validation library with a good security posture. The main concerns are: (1) potential ReDoS vulnerabilities in regex patterns used for validation, (2) security implications of supporting custom validator functions, (3) reflection-based attack surface for denial of service, and (4) lack of explicit security policy. Dependencies are relatively current with dependabot configured for monitoring. No hardcoded secrets, SQL injection risks, or XSS vulnerabilities were identified in the file structure. Recommendations focus on regex analysis, custom validator security documentation, reflection safety measures, and establishing a formal security disclosure process.
- High · Outdated Golang Standard Library Dependencies —
_examples/validate_fn/go.mod. The go.mod file references golang.org/x/crypto v0.36.0, golang.org/x/net v0.38.0, and golang.org/x/text v0.23.0. These versions are relatively recent but should be monitored for CVEs. The toolchain specifies go1.24.4 which should be kept updated. Fix: Regularly run 'go mod tidy' and 'go get -u' to update dependencies. Monitor golang security advisories and consider using dependabot (already configured) for automated dependency updates. - Medium · Potential Regex Denial of Service (ReDoS) in Validation Rules —
regexes.go, postcode_regexes.go. The codebase contains files like 'regexes.go', 'postcode_regexes.go', and 'country_codes.go' that likely define regex patterns for validation. If these regexes are not carefully constructed, they could be vulnerable to ReDoS attacks when processing untrusted input, especially for postcode and similar pattern validations. Fix: Review all regex patterns for potential catastrophic backtracking. Use regex analysis tools like 'regexploit' to identify vulnerable patterns. Consider using timeouts on regex operations and simplifying complex patterns. - Medium · Custom Validation Function Security —
_examples/validate_fn, validate_fn.go, field_level.go. The repository supports custom validation functions (indicated by '_examples/validate_fn' and 'no_validate_fn.go'). If custom validators are user-provided without proper sandboxing, they could execute arbitrary code or access sensitive data during validation. Fix: Document security best practices for custom validators. Implement input sanitization for validator parameters. Consider adding warnings in documentation about sandbox limitations of custom validators. - Medium · Unvalidated Struct Reflection —
field_level.go, struct_level.go, baked_in.go. As a struct validation library, the codebase heavily relies on Go's reflection capabilities. Improper handling of reflected values or untrusted struct definitions could potentially be exploited to cause denial of service through excessive memory allocation or CPU consumption. Fix: Implement depth limits for nested struct validation. Add timeout mechanisms for validation operations. Test with deeply nested or pathological struct definitions to identify performance issues. - Low · Missing Input Size Limits on String Validations —
baked_in.go. String validation rules like 'len', 'min', 'max' may not account for extremely large input strings, potentially causing memory exhaustion or slow validation operations when processing untrusted input. Fix: Document recommended maximum input sizes for validators. Consider adding optional limits to prevent processing of unreasonably large inputs. Implement early termination for excessively long string validations. - Low · No Explicit Security Policy —
Repository root. While a MAINTAINERS.md file exists, there is no visible SECURITY.md or security policy file for responsible disclosure of vulnerabilities. Fix: Create a SECURITY.md file following the GitHub Security Policy template. Define a responsible disclosure process and security contact information.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.