GDPR Art. 7(3) states that a data subject has the right to withdraw consent at any time, and Recital 32 clarifies that consent must be granular and specific to each purpose. When new tracking purposes or third parties are added without re-prompting users, the original consent — even if validly obtained — no longer covers the new processing. ePrivacy Art. 5(3) ties the scope of consent to the specific purposes declared at the time of collection. A user who consented to analytics-only in 2024 has not consented to the marketing pixel added in 2025, and treating their stored preference as blanket consent for all future additions is unlawful.
Medium because the failure only affects users with previously stored consent — it does not affect new visitors — but it invalidates consent for all returning users when new tracking is added without triggering re-consent.
Store a consent version alongside the user's decision and compare it to a CONSENT_VERSION constant on every page load. Bump the constant whenever you add a new third-party service or cookie category.
// src/lib/consent.ts
const CONSENT_VERSION = '1.1' // was '1.0' — bumped when Segment was added
export function needsConsent(): boolean {
const raw = localStorage.getItem('cookie_consent')
if (!raw) return true
const stored = JSON.parse(raw)
return !stored.version || stored.version !== CONSENT_VERSION
}
Add bumping CONSENT_VERSION to your team's checklist for adding any new analytics tool, ad pixel, or embedded third-party service. The banner will automatically re-appear for returning users whose stored version predates the change.
ID: cookie-consent-compliance.consent-enforcement.re-consent-after-changes
Severity: medium
What to look for: Find where the stored consent version is compared against the current banner version. Look in the consent initialization logic (the useEffect that reads localStorage on page load). Is there a version check: if (stored.version !== CURRENT_BANNER_VERSION) { showBanner() }? Check what value is stored for the version and whether there is a corresponding constant in the codebase that would be bumped when the banner changes. Also check whether the consent platform (if using Cookiebot, OneTrust, etc.) is configured to re-prompt on version change — these platforms typically handle this automatically via their "script version" or "configuration version" mechanisms, but it must be enabled. Look for a CONSENT_VERSION or BANNER_VERSION constant in the consent library or component.
Pass criteria: Count all consent version or policy change detection mechanisms. A consent version is stored alongside the consent decision. On page load, the stored version is compared to the current banner version. When they differ (because new cookies or third parties were added), the banner is shown again and the user must re-consent. The version comparison logic is present in code. At least 1 mechanism must exist to detect policy changes and re-prompt users.
Fail criteria: No version field in the stored consent object. Consent stored once and never refreshed even when new tracking is added. No mechanism to prompt returning users who previously consented when the cookie inventory changes.
Skip (N/A) when: No consent banner exists (already failing at banner-first-visit).
Detail on fail: Example: "Stored consent object contains only {analytics: true, marketing: false} with no version or timestamp. No mechanism to re-prompt users when cookie inventory changes." or "CONSENT_VERSION constant found (value: '1') but no version comparison in the banner initialization useEffect.".
Remediation: Add a version check in your src/lib/consent.ts:
const CONSENT_VERSION = '1.1'
export function needsConsent(): boolean {
const stored = JSON.parse(localStorage.getItem('consent') || '{}')
return !stored.version || stored.version !== CONSENT_VERSION
}
Bump CONSENT_VERSION whenever you add new third-party services or cookies.