You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Provide a high-level summary of the proposed change. Keep it short.
Proposing to deprecate -duc / -disable-update-check and replace the current "check for updates every run" behavior with a cached, periodic update-check flow backed by Otter pkg. Basically: don't check every single time, just cache it for N days and reuse the persistent metadata store.
This makes update checks more efficient, less noisy, and more in line with modern CLI best practices.
Motivation
Tip
Describe the need, problem, and motivation for the proposed feature or change. Provide any context necessary to understand the motivation. This may include links to previous related GitHub Issues/Discussions and Discord chats, if applicable.
The current update-check runs every single damn time Nuclei executes, which wastes network calls, adds latency, and pushes many users to disable it entirely. Since we already have Otter pkg to implement persistent (templates) metadata cache (#6630), we can use that pkg too to store the last update check timestamp and avoid doing this on every run.
This also follows what most modern CLI tools do. They do NOT check for updates on each run; instead they cache the last check and only refresh occasionally. Some common examples:
GitHub CLI (gh): checks roughly every 24 hours, stores data in cache, never on every run
Terraform: caches last update check and only refreshes daily
npm / yarn / pnpm: use update-notifier, checking every 1–3 days, storing timestamps in user's home directory
Homebrew: avoids checking on every command; uses timed intervals to prevent unnecessary GitHub API hits
Rustup: checks occasionally, not per-run; allows manual forcing
Across the board, the rule is: avoid update checks on every run; instead, check occasionally and remember the last result. Nuclei's current approach (checking every run) is more aggressive than almost all of these tools, which is why deprecating -duc and moving to a smarter, cached mechanism makes more sense.
Detailed Design
Tip
Explain the design solution in detail for those familiar with the language to understand and for those familiar with the compiler to implement. Include examples of how the feature is used, such as new command-line flags or interface changes. This may include design assumptions, conventions, API specs (though not always required), code snippets, data flow or sequence diagrams, etc.
Keep compatibility with old flag for a limited time.
Defaults
Suggested default interval: 1 day.
Impacts / Unresolved Questions
Tip
List key impacts, open questions, and trade-offs of the design. Include potential negative or controversial impacts, security implications, alternatives, and core concepts. Highlight pros and cons of important decisions. This info can be reused to update project docs, guides, and FAQs. Reviewers are also welcome to add their questions in this section.
Impact
encoding/gob is fast and efficient, serializing a small struct like UpdateState is negligible overhead.
Since metadata is small, storage footprint is minimal; no impact on performance/memory.
The update-check path is only triggered rarely (once per interval), so there is no significant runtime overhead for typical users.
Unresolved Questions
How many days should be the default interval? (1-7 days)
Should binary + template update checks share the same schedule?
Future Milestones (Optional)
Tip
List things that the design will enable but that are out of scope for now. This can help understand the greater impact of a proposal without requiring to extend the scope of a proposal unnecessarily.
TBD.
Implementation Details (Optional)
Tip
This section may include implementation details such as testing plans, update/rollback compatibility, scalability considerations, API impacts, resource usage, SLI/SLO effects, and implementation phases. It can help track major milestones and correlate them with project issues, PRs, and releases.
Use Otter as the on-disk key/value metadata store.
Define a struct to hold update-check state, see detailed design above.
On startup (or first run), attempt to load the state:
When performing an update check (because cache expired or forced), after success, save back.
Since Otter persistently serializes values (using encoding/gob under the hood), we get binary-encoded, efficient disk storage with minimal dependencies. This matches how Otter is already used elsewhere, such in (templates) metadata caching. encoding/gob is native, efficient, and can encode Go-specific types reliably.
Using Otter's existing API keeps code clean and avoids ad-hoc file system hacks. YKWIM.
Integration steps & flag deprecation plan
Deprecation of -duc/-disable-update-check:
On first release with this change: when the flag is provided, print a warning: "[WRN] -disable-update-check is deprecated and will be removed in the future release"
Keep it functionally equivalent (i.e. skip update check) for backward compatibility.
New flags:
-force-update-check: always run update check regardless of cache.
Default behavior:
If no flags: read metadata, if last check is older than interval then check; otherwise skip quietly.
If metadata not found or corrupted: treat as "never checked", do check, write metadata.
Failure resilience:
If Otter read fails (e.g. corrupted file): log a warning, but proceed with update check (fail-open), then reset metadata.
If Otter write fails (e.g. disk full): log error, but don't block execution. Future runs will attempt again.
Behavior when metadata file is corrupted or unreadable (simulate read error).
Round-trip encode/decode tests: ensure UpdateState serializes via Otter/gob and deserializes correctly. encoding/gob is stable: adding new fields later is possible without breaking older data (gob ignores unknown fields)
Migration and backward compatibility:
No migration needed for users who used -duc, because behavior remains identical for a transitional period.
In release notes, clearly state that -disable-update-check is deprecated and will be removed after two releases (per deprecation timeline).
Deprecation Timeline
Version
Change
v3.7.0
Mark -duc / -disable-update-check as deprecated. Add deprecation warnings in CLI help and runtime logs.
v4.0.0
Fully remove the flag and all related code paths. Update documentation and migration guides accordingly.
Error Handling & Safety
Ensure Otter operations (Get/Set) are thread-safe and safe in concurrent runs (e.g. multiple Nuclei invocations). If Otter already supports concurrency (as used by template cache), rely on that; otherwise, guard with locking.
For encoding/gob decoding: decode into pointer, check for error. If decode fails, treat as "no valid metadata", re-check updates, and overwrite metadata. encoding/gob's design is tolerant of missing or extra fields between versions, which helps for future compatibility.
No need for complex index or chunking, since we only store a single struct, keeping all state in one key-value entry avoids multi-chunk encoding/gob issues. (Storing multiple Encode calls into the same encoding/gob file can lead to problems, encoding/gob expects a single stream per session.
Summary
Tip
Provide a high-level summary of the proposed change. Keep it short.
Proposing to deprecate
-duc/-disable-update-checkand replace the current "check for updates every run" behavior with a cached, periodic update-check flow backed by Otter pkg. Basically: don't check every single time, just cache it for N days and reuse the persistent metadata store.This makes update checks more efficient, less noisy, and more in line with modern CLI best practices.
Motivation
Tip
Describe the need, problem, and motivation for the proposed feature or change. Provide any context necessary to understand the motivation. This may include links to previous related GitHub Issues/Discussions and Discord chats, if applicable.
The current update-check runs every single damn time Nuclei executes, which wastes network calls, adds latency, and pushes many users to disable it entirely. Since we already have Otter pkg to implement persistent (templates) metadata cache (#6630), we can use that pkg too to store the last update check timestamp and avoid doing this on every run.
This also follows what most modern CLI tools do. They do NOT check for updates on each run; instead they cache the last check and only refresh occasionally. Some common examples:
update-notifier, checking every 1–3 days, storing timestamps in user's home directoryAcross the board, the rule is: avoid update checks on every run; instead, check occasionally and remember the last result. Nuclei's current approach (checking every run) is more aggressive than almost all of these tools, which is why deprecating
-ducand moving to a smarter, cached mechanism makes more sense.Detailed Design
Tip
Explain the design solution in detail for those familiar with the language to understand and for those familiar with the compiler to implement. Include examples of how the feature is used, such as new command-line flags or interface changes. This may include design assumptions, conventions, API specs (though not always required), code snippets, data flow or sequence diagrams, etc.
Mechanism
-duc/-disable-update-check.~/.cache/nuclei/update-state.gob.LastUpdateCheckis withinFlags
-force-update-checkDefaults
Suggested default interval: 1 day.
Impacts / Unresolved Questions
Tip
List key impacts, open questions, and trade-offs of the design. Include potential negative or controversial impacts, security implications, alternatives, and core concepts. Highlight pros and cons of important decisions. This info can be reused to update project docs, guides, and FAQs. Reviewers are also welcome to add their questions in this section.
Impact
encoding/gobis fast and efficient, serializing a small struct likeUpdateStateis negligible overhead.Unresolved Questions
Future Milestones (Optional)
Tip
List things that the design will enable but that are out of scope for now. This can help understand the greater impact of a proposal without requiring to extend the scope of a proposal unnecessarily.
TBD.
Implementation Details (Optional)
Tip
This section may include implementation details such as testing plans, update/rollback compatibility, scalability considerations, API impacts, resource usage, SLI/SLO effects, and implementation phases. It can help track major milestones and correlate them with project issues, PRs, and releases.
encoding/gobunder the hood), we get binary-encoded, efficient disk storage with minimal dependencies. This matches how Otter is already used elsewhere, such in (templates) metadata caching.encoding/gobis native, efficient, and can encode Go-specific types reliably.Integration steps & flag deprecation plan
Deprecation of
-duc/-disable-update-check:"[WRN] -disable-update-check is deprecated and will be removed in the future release"New flags:
-force-update-check: always run update check regardless of cache.Default behavior:
Failure resilience:
Testing & Validation:
-force-update-check.UpdateStateserializes via Otter/gob and deserializes correctly.encoding/gobis stable: adding new fields later is possible without breaking older data (gob ignores unknown fields)Migration and backward compatibility:
-duc, because behavior remains identical for a transitional period.-disable-update-checkis deprecated and will be removed after two releases (per deprecation timeline).Deprecation Timeline
-duc/-disable-update-checkas deprecated. Add deprecation warnings in CLI help and runtime logs.Error Handling & Safety
Get/Set) are thread-safe and safe in concurrent runs (e.g. multiple Nuclei invocations). If Otter already supports concurrency (as used by template cache), rely on that; otherwise, guard with locking.encoding/gobdecoding: decode into pointer, check for error. If decode fails, treat as "no valid metadata", re-check updates, and overwrite metadata.encoding/gob's design is tolerant of missing or extra fields between versions, which helps for future compatibility.encoding/gobissues. (Storing multiple Encode calls into the sameencoding/gobfile can lead to problems,encoding/gobexpects a single stream per session.References
Normative:
Informative:
Reviewer approval: