faker-ruby/faker · error · ArgumentError
Invalid birthday: #{birthday}. Danish CPR numbers are only d
Error message
Invalid birthday: #{birthday}. Danish CPR numbers are only distributed to persons born between 1858 and 2057. What it means
Raised by the private danish_control_digits helper in Faker::IdNumber.danish_id_number when the birthday's century is 18xx but the two-digit year is below 58. The Danish CPR sequence-number scheme only encodes birth years from 1858 onward (century digit 5/6/7/8 with year digits >= 58), so a date in 1800-1857 has no valid control digit and the method raises ArgumentError instead of generating an invalid number.
Source
Thrown at lib/faker/default/id_number.rb:393
subtraction = 11 - remainder.to_i
digits = { 10 => 'X', 11 => '0' }
digits.include?(subtraction) ? digits[subtraction] : subtraction.to_s
end
def danish_control_digits(birthday)
year = birthday.year
century = year.to_s.slice(0, 2).to_i
year_digits = year.to_s.slice(2, 2).to_i
error_message = "Invalid birthday: #{birthday}. Danish CPR numbers are only distributed to persons born between 1858 and 2057."
case century
when 18
# If 5, 6, 7 or 8 and the year numbers are greater than or equal to 58, you were born in 18XX.
case year_digits
when 58..99
[5, 6, 7, 8]
else
raise ArgumentError, error_message
end
when 19
# If 0, 1, 2 or 3, you are always born in 19XX.
# If 4 or 9, you are born in 19XX if the year digits are greater than 36.
case year_digits
when 0..36
[0, 1, 2, 3]
else # 37..99
[0, 1, 2, 3, 4, 9]
end
else
# If 4, 5, 6, 7, 8 or 9 and the year digits are less than or equal to 36, you were born in 20XX.
# 5, 6, 7 and 8 are not distributed to persons, with year digits from and including 37 to and including 57.
case year_digits
when 0..36
[4, 5, 6, 7, 8, 9]
when 37..57View on GitHub (pinned to cca4184947)
Solutions
- Use a birthday between 1858-01-01 and 2057-12-31, e.g. Date.new(1890, 5, 3).
- Clamp or validate user-supplied birthdates before passing them: raise or substitute a default when the year is outside 1858..2057.
- If you truly need IDs for pre-1858 persons, CPR cannot represent them; generate a plain numeric identifier instead of a CPR number.
Example fix
# before Faker::IdNumber.danish_id_number(birthday: Date.new(1850, 1, 1)) # ArgumentError # after Faker::IdNumber.danish_id_number(birthday: Date.new(1859, 1, 1))
Defensive patterns
Strategy: validation
Validate before calling
def cpr_compatible_birthday?(date) date.year.between?(1858, 2057) end birthday = Date.new(1990, 3, 5) if !cpr_compatible_birthday?(user_birthday) Faker::IdNumber.danish_id_number(birthday: birthday)
Type guard
def cpr_compatible_birthday?(date) date.is_a?(Date) && date.year.between?(1858, 2057) end
Try / catch
begin Faker::IdNumber.danish_id_number(birthday: birthday) rescue ArgumentError Faker::IdNumber.danish_id_number(birthday: Faker::Date.birthday) # fall back to default range end
Prevention
- Assert 1858 <= birthday.year <= 2057 before calling danish_id_number.
- Validate parsed free-text dates at the boundary (a mistyped year is the usual cause).
- Remember the same range applies to the upper bound: 2058+ also raises.
When it happens
Trigger: Faker::IdNumber.danish_id_number(birthday: Date.new(1812, 5, 3)) or any birthday between 1800-01-01 and 1857-12-31: century == 18 and year_digits falls outside 58..99, hitting the raise at lib/faker/default/id_number.rb:393.
Common situations: Seeding historical test data with very old birthdates; passing Date.parse of free-text user input that contains a mistyped year (e.g. 1050 or 1850 instead of 1950); factories that randomize birthdays over centuries (Faker::Date.birthday defaults to a recent range, so this only occurs with explicit dates).
Related errors
- Invalid gender #{gender}. Must be one of male, female, or be
- Search terms must be specified for grayscale images
- Search terms must be specified for pixelated images
- Search terms must be specified for colorized images
- Supported colorizations are #{SUPPORTED_COLORIZATIONS.join('
AI-assisted analysis of faker-ruby/faker@cca4184947 (2026-08-21).
Data as JSON: /api/errors/8b93de2761dc0b53.
Report an issue: GitHub.