phone number standards

Sent logo
Sent TeamMar 8, 2026 / phone number standards / Article

Malaysia Phone Number Format: Complete Validation Guide & E.164 Conversion (2025)

Master Malaysian phone number validation with code examples in JavaScript, Python, PHP & Java. Includes MCMC regulations, E.164 conversion, WhatsApp formatting, IRBM e-invoice compliance, and mobile carrier prefixes for Maxis, Celcom, DiGi & U Mobile.

Malaysia Phone Numbers: Complete Format, Validation & E.164 Guide (2025)

Learn how to format, validate, and implement Malaysian phone numbers in your applications. This guide covers everything from MCMC regulations to E.164 conversion – essential for building web applications, managing customer databases, and developing telecommunications platforms. Whether you're implementing SMS messaging systems, WhatsApp integrations, or ensuring IRBM e-invoice compliance, this guide provides the validation rules and code examples you need.

Understanding Malaysian Phone Number Structure

The Malaysian Communications and Multimedia Commission (MCMC) regulates Malaysia's phone number system, which adheres to international standards while incorporating unique regional variations. Here's the structure:

  • Country Code: +60 (Required for international calls and E.164 format)
  • National Prefix: 0 (Used for domestic calls within Malaysia)
  • Area Code/Mobile Prefix: Distinguishes between fixed lines, mobile carriers (Maxis, Celcom, DiGi, U Mobile), and special services
  • Subscriber Number: The unique identifier for a specific phone line

What Are the Malaysian Phone Number Formats and Validation Rules?

1. How to Validate Fixed Line Numbers in Malaysia

  • Format: 0X-XXXX XXXX (X represents digits 3–9)
  • Example: 03-87654321 (Kuala Lumpur landline)
  • Validation Regex: ^0[3-9]-\d{7,8}$ (Accounts for both 7 and 8 digit subscriber numbers after the area code, accommodating variations across regions. Enforces the hyphen.)
  • Area Codes: Geographically assigned. In Peninsular Malaysia, area codes are one digit (3, 4, 5, 6, 7, 9), while East Malaysia (Sabah and Sarawak) uses two-digit area codes (e.g., 82 for Kuching, 88 for Kota Kinabalu). For example, 03 serves Kuala Lumpur, Putrajaya, and parts of Selangor.
  • Subscriber Number Length: Landline subscriber numbers are 8 digits in area code 3 (Kuala Lumpur, Selangor, Putrajaya), 7 digits in other Peninsular Malaysia areas, and 6 digits in East Malaysia.
  • Implementation Notes: Store the full national number, including the leading 0, for domestic use. When formatting for display, maintain the hyphen between the area code and subscriber number.

Complete Area Code Reference Table

According to MCMC regulations, Malaysian area codes follow this structure:

Area CodeRegion/StateSubscriber DigitsExample
03Selangor, Kuala Lumpur, Putrajaya, Genting Highlands (Pahang)803-2xxx xxxx
04Perlis, Kedah, Penang, Pengkalan Hulu (Perak)704-2xx xxxx
05Perak, Cameron Highlands (Pahang), Hulu Bernam (Selangor)705-2xx xxxx
06Negeri Sembilan, Malacca, Muar/Tangkak/Batu Anam (Johor)706-2xx xxxx
07Johor, Gemas (Negeri Sembilan)707-2xx xxxx
09Pahang, Terengganu, Kelantan709-2xx xxxx
082Sarawak (Kuching, Samarahan, Serian)6082-2x xxxx
083Sarawak (Sri Aman, Betong)6083-2x xxxx
084Sarawak (Sibu, Sarikei, Mukah, Kapit)6084-2x xxxx
085Sarawak (Miri, Limbang, Lawas)6085-2x xxxx
086Sarawak (Bintulu, Belaga)6086-2x xxxx
087Sabah (Labuan, Interior Division)6087-2x xxxx
088Sabah (Kota Kinabalu, Kudat)6088-2x xxxx
089Sabah (Lahad Datu, Sandakan, Tawau)6089-2x xxxx

Note: Area code 02 was formerly used for direct dialing to Singapore but was discontinued in May–July 2017. Area code 080 is reserved for domestic access from East Malaysia to Brunei. Area code 081 is reserved for future use.

Fixed Line Validation Code Examples

JavaScript:

javascript
function validateMalaysianLandline(number) {
  // Remove spaces and validate format
  const cleaned = number.replace(/\s+/g, '');

  // Area code 3: 10 digits total (0 + 1 digit area code + 8 digits)
  const area3Regex = /^03-?\d{8}$/;

  // Other Peninsular Malaysia: 9 digits total (0 + 1 digit area code + 7 digits)
  const peninsularRegex = /^0[4-79]-?\d{7}$/;

  // East Malaysia: 9 digits total (0 + 2 digit area code + 6 digits)
  const eastMalaysiaRegex = /^08[2-9]-?\d{6}$/;

  return area3Regex.test(cleaned) ||
         peninsularRegex.test(cleaned) ||
         eastMalaysiaRegex.test(cleaned);
}

// Examples
console.log(validateMalaysianLandline("03-87654321")); // true (KL)
console.log(validateMalaysianLandline("04-2345678"));  // true (Penang)
console.log(validateMalaysianLandline("082-234567"));  // true (Kuching)

Python:

python
import re

def validate_malaysian_landline(number):
    """Validate Malaysian landline numbers according to MCMC format."""
    # Remove spaces
    cleaned = number.replace(" ", "")

    # Area code 3: 10 digits total
    area3_pattern = r'^03-?\d{8}$'

    # Other Peninsular Malaysia: 9 digits total
    peninsular_pattern = r'^0[4-79]-?\d{7}$'

    # East Malaysia: 9 digits total
    east_malaysia_pattern = r'^08[2-9]-?\d{6}$'

    return bool(re.match(area3_pattern, cleaned) or
                re.match(peninsular_pattern, cleaned) or
                re.match(east_malaysia_pattern, cleaned))

# Examples
print(validate_malaysian_landline("03-87654321"))  # True (KL)
print(validate_malaysian_landline("04-2345678"))   # True (Penang)
print(validate_malaysian_landline("082-234567"))   # True (Kuching)

PHP:

php
function validateMalaysianLandline($number) {
    // Remove spaces
    $cleaned = str_replace(' ', '', $number);

    // Area code 3: 10 digits total
    $area3Pattern = '/^03-?\d{8}$/';

    // Other Peninsular Malaysia: 9 digits total
    $peninsularPattern = '/^0[4-79]-?\d{7}$/';

    // East Malaysia: 9 digits total
    $eastMalaysiaPattern = '/^08[2-9]-?\d{6}$/';

    return preg_match($area3Pattern, $cleaned) ||
           preg_match($peninsularPattern, $cleaned) ||
           preg_match($eastMalaysiaPattern, $cleaned);
}

// Examples
var_dump(validateMalaysianLandline("03-87654321")); // true (KL)
var_dump(validateMalaysianLandline("04-2345678"));  // true (Penang)
var_dump(validateMalaysianLandline("082-234567"));  // true (Kuching)

2. How to Validate Malaysian Mobile Numbers

  • Format: 01X-XXXX XXXX (X represents digits 0–9)
  • Example: 012-3456789 (7-digit subscriber number), 011-23456789 (8-digit subscriber number)
  • Subscriber Number Length: Numbers with prefixes 011 and 015 have 8-digit subscriber numbers (11 digits total including leading 0), while all other mobile prefixes have 7-digit subscriber numbers (10 digits total including leading 0).
  • Validation Regex: ^01[0-9]-\d{7,8}$ (Accounts for 7 or 8 digit subscriber numbers following the 01X prefix. Note that some MVNOs might use slightly different formats.)
  • Mobile Number Portability (MNP): Implemented in Malaysia on October 1, 2008. Since MNP is active, the prefix no longer definitively identifies the carrier. However, as of 2025, Malaysia's MNP service has a high rejection rate (over 50% of porting requests are rejected), compared to best practice services which have rejection rates below 10%. Consider using a carrier lookup service for accurate routing if necessary.
  • Prefix Allocation: While prefixes are associated with operators, the ranges can be complex. Refer to the MCMC or operator websites for the most up-to-date allocations. The detailed breakdown below provides current prefix ranges.

Mobile Prefix-to-Carrier Mapping Table

According to MCMC data, the following table shows the current mobile prefix allocations (as of 2025). Note that due to MNP, these prefixes indicate the original carrier only:

PrefixDigitsOperator/MVNOExamples
0107Celcom, XOX, UniFi Mobile, Tune Talk010-2xxxxxx, 010-36xxxxx
0118UniFi Mobile, redONE, U Mobile, Maxis, XOX, Celcom, Tune Talk, DiGi, Yes 4G, Telekom Malaysia, Altel, BuzzME, Friendi011-100xxxxx to 011-605xxxxx
0127Maxis012-2xxxxxx to 012-9xxxxxx
0137Celcom013-2xxxxxx to 013-9xxxxxx
0147Maxis, DiGi, Tune Talk, Celcom014-2xxxxxx to 014-9xxxxxx
0158Onesmart Mobile, BluePack Network, B&E Wireless, Telekom Malaysia (TSoIP), Time Fibre, RedTone, Y-Max, Webe, Maxis, OCE, DiGi (data only), Celcom (data only)015-1xxxxxxx to 015-9xxxxxxx
0167DiGi016-2xxxxxx to 016-9xxxxxx
0177Maxis017-2xxxxxx to 017-9xxxxxx
0187U Mobile, Yes 4G018-12xxxxx, 018-2xxxxxx
0197Celcom019-2xxxxxx to 019-9xxxxxx

Key Carriers:

  • Celcom: 010, 013, 019, and shared ranges in 011, 014, 015
  • Maxis: 012, 017, and shared ranges in 011, 014, 015
  • DiGi: 016, and shared ranges in 011, 014, 015
  • U Mobile: 018, and shared ranges in 011
  • Yes 4G: 018, and shared ranges in 011
  • UniFi Mobile: 010, and shared ranges in 011
  • Tune Talk: 010, and shared ranges in 011, 014

Mobile Number Validation Code Examples

JavaScript:

javascript
function validateMalaysianMobile(number) {
  // Remove spaces and hyphens
  const cleaned = number.replace(/[\s-]/g, '');

  // 011 and 015: 11 digits (including leading 0)
  const long11Regex = /^0(11|15)\d{8}$/;

  // All other 01X prefixes: 10 digits (including leading 0)
  const standard10Regex = /^01[02-46-9]\d{7}$/;

  return long11Regex.test(cleaned) || standard10Regex.test(cleaned);
}

// Examples
console.log(validateMalaysianMobile("012-3456789"));   // true (Maxis, 10 digits)
console.log(validateMalaysianMobile("011-12345678"));  // true (U Mobile, 11 digits)
console.log(validateMalaysianMobile("016-7654321"));   // true (DiGi, 10 digits)
console.log(validateMalaysianMobile("015-98765432"));  // true (VoIP, 11 digits)

Python:

python
import re

def validate_malaysian_mobile(number):
    """Validate Malaysian mobile numbers with proper length handling."""
    # Remove spaces and hyphens
    cleaned = number.replace(" ", "").replace("-", "")

    # 011 and 015: 11 digits total
    long_pattern = r'^0(11|15)\d{8}$'

    # All other 01X prefixes: 10 digits total
    standard_pattern = r'^01[02-46-9]\d{7}$'

    return bool(re.match(long_pattern, cleaned) or
                re.match(standard_pattern, cleaned))

# Examples
print(validate_malaysian_mobile("012-3456789"))   # True (Maxis, 10 digits)
print(validate_malaysian_mobile("011-12345678"))  # True (U Mobile, 11 digits)
print(validate_malaysian_mobile("016-7654321"))   # True (DiGi, 10 digits)
print(validate_malaysian_mobile("015-98765432"))  # True (VoIP, 11 digits)

PHP:

php
function validateMalaysianMobile($number) {
    // Remove spaces and hyphens
    $cleaned = str_replace([' ', '-'], '', $number);

    // 011 and 015: 11 digits total
    $longPattern = '/^0(11|15)\d{8}$/';

    // All other 01X prefixes: 10 digits total
    $standardPattern = '/^01[02-46-9]\d{7}$/';

    return preg_match($longPattern, $cleaned) ||
           preg_match($standardPattern, $cleaned);
}

// Examples
var_dump(validateMalaysianMobile("012-3456789"));   // true (Maxis, 10 digits)
var_dump(validateMalaysianMobile("011-12345678"));  // true (U Mobile, 11 digits)
var_dump(validateMalaysianMobile("016-7654321"));   // true (DiGi, 10 digits)
var_dump(validateMalaysianMobile("015-98765432"));  // true (VoIP, 11 digits)

Java:

java
import java.util.regex.Pattern;

public class MalaysianPhoneValidator {
    private static final Pattern LONG_PATTERN = Pattern.compile("^0(11|15)\\d{8}$");
    private static final Pattern STANDARD_PATTERN = Pattern.compile("^01[02-46-9]\\d{7}$");

    public static boolean validateMalaysianMobile(String number) {
        // Remove spaces and hyphens
        String cleaned = number.replaceAll("[\\s-]", "");

        return LONG_PATTERN.matcher(cleaned).matches() ||
               STANDARD_PATTERN.matcher(cleaned).matches();
    }

    public static void main(String[] args) {
        System.out.println(validateMalaysianMobile("012-3456789"));   // true
        System.out.println(validateMalaysianMobile("011-12345678"));  // true
        System.out.println(validateMalaysianMobile("016-7654321"));   // true
    }
}

3. What Are Malaysia's Special Service Numbers?

  • Toll-Free: 1800-XX-XXXX (7 digits after 1800)
  • Premium Rate: Multiple prefixes exist for premium services:
    • 1-300-XX-XXXX: Local rate telephone numbers
    • 1-700-XX-XXXX: Personal numbering service
    • 1-900-XX-XXXX: Multimedia service numbers
    • 600-XX-XXXX: Audiotext hosting and premium-rate numbers
  • Emergency Services: 999 (for police, fire, and ambulance) and 112 (international emergency number)
  • Short Codes: Various shortcodes exist for specific services (e.g., directory assistance, time announcements). These typically have 3–6 digits.

Comprehensive List of Special Service Numbers

According to MCMC regulations, the following special service numbers are available:

Number/PrefixServiceCost
999Malaysian General Emergency Service (Police, Fire, Ambulance)FREE
112International Emergency NumberFREE
997National Scam Response Centre (NSRC)FREE
100General telephone servicesVaries
101Operator assistance (domestic calls)Varies
102Service assistanceVaries
103Fixed telephone line directory assistanceVaries (RM1.50/call on some networks)
104Telegram servicesVaries
1051Time announcementRM0.10–1.50/call depending on carrier
1066Earthquakes and Tsunami Alert CentreVaries
108Operator assistance (international calls)Varies
15454Tenaga Nasional Berhad (electricity fault reporting)RM0.15/30 sec (Celcom), RM0.30/min (Digi)
15999Talian Kasih (emotional support & counseling)FREE on most networks
1800-XX-XXXXToll-free numbersFREE from landlines, local rate from mobile
1300-XX-XXXXLocal rate telephone numbersRM0.30–0.36/min
1700-XX-XXXXPersonal numbering serviceRM0.60/min
1900-XX-XXXXMultimedia service numbersPremium rate
600-XX-XXXXAudiotext hosting and premium-rateVariable rates based on prefix (600-81 to 600-86)

Premium Rate 600 Numbers Pricing (Peak/Off-Peak):

  • 600-81: RM0.13/min (peak), RM0.09–0.20/min (off-peak)
  • 600-82: RM0.39/min (peak), RM0.20/min (off-peak)
  • 600-83: RM0.78/min (peak), RM0.39/min (off-peak)
  • 600-84: RM1.30/min (peak), RM0.65/min (off-peak)
  • 600-85: RM1.95/min (peak), RM0.98/min (off-peak)
  • 600-86: RM1.95–3.90/min (peak), RM0.98–1.95/min (off-peak)

Source: CelcomDigi Special Rates

Special Number Validation Code Examples

JavaScript:

javascript
function validateMalaysianSpecialNumber(number) {
  const cleaned = number.replace(/[\s-]/g, '');

  // Emergency services
  if (/^(999|112|997)$/.test(cleaned)) return { valid: true, type: 'emergency' };

  // Toll-free
  if (/^1800\d{6}$/.test(cleaned)) return { valid: true, type: 'toll-free' };

  // Local rate
  if (/^1300\d{6}$/.test(cleaned)) return { valid: true, type: 'local-rate' };

  // Personal numbering
  if (/^1700\d{6}$/.test(cleaned)) return { valid: true, type: 'personal' };

  // Multimedia service
  if (/^1900\d{6}$/.test(cleaned)) return { valid: true, type: 'multimedia' };

  // Premium rate audiotext
  if (/^600[8][1-6]\d{4}$/.test(cleaned)) return { valid: true, type: 'premium' };

  // Short codes (3-6 digits)
  if (/^(100|10[1-8]|1051|1066|15454|15999)$/.test(cleaned)) return { valid: true, type: 'service' };

  return { valid: false, type: null };
}

// Examples
console.log(validateMalaysianSpecialNumber("999"));        // { valid: true, type: 'emergency' }
console.log(validateMalaysianSpecialNumber("1800123456")); // { valid: true, type: 'toll-free' }
console.log(validateMalaysianSpecialNumber("1300654321")); // { valid: true, type: 'local-rate' }

Python:

python
import re

def validate_malaysian_special_number(number):
    """Validate Malaysian special service numbers."""
    cleaned = number.replace(" ", "").replace("-", "")

    # Emergency services
    if re.match(r'^(999|112|997)$', cleaned):
        return {'valid': True, 'type': 'emergency'}

    # Toll-free
    if re.match(r'^1800\d{6}$', cleaned):
        return {'valid': True, 'type': 'toll-free'}

    # Local rate
    if re.match(r'^1300\d{6}$', cleaned):
        return {'valid': True, 'type': 'local-rate'}

    # Personal numbering
    if re.match(r'^1700\d{6}$', cleaned):
        return {'valid': True, 'type': 'personal'}

    # Multimedia service
    if re.match(r'^1900\d{6}$', cleaned):
        return {'valid': True, 'type': 'multimedia'}

    # Premium rate audiotext
    if re.match(r'^600[8][1-6]\d{4}$', cleaned):
        return {'valid': True, 'type': 'premium'}

    # Short codes
    if re.match(r'^(100|10[1-8]|1051|1066|15454|15999)$', cleaned):
        return {'valid': True, 'type': 'service'}

    return {'valid': False, 'type': None}

# Examples
print(validate_malaysian_special_number("999"))        # {'valid': True, 'type': 'emergency'}
print(validate_malaysian_special_number("1800123456")) # {'valid': True, 'type': 'toll-free'}

4. How to Convert Malaysian Numbers to E.164 Format

  • Format: +60XXXXXXXXXX (Remove the leading 0 and any hyphens or spaces)
  • Example: +60387654321
  • Implementation: Store numbers in E.164 format for database storage and international compatibility. Convert numbers to the local format for display purposes.
  • IRBM e-Invoice Compliance: As of April 12, 2025, Malaysia's Inland Revenue Board (IRBM) requires all phone numbers in e-invoices to follow E.164 format. This means phone numbers must start with +, include the country code +60, and contain no spaces, hyphens, or parentheses (e.g., +60123456789 not 012-345 6789).

How to Implement Malaysian Phone Number Validation in Your Application

javascript
function toE164(malaysianNumber) {
  // Remove spaces, hyphens, and leading zero
  const cleaned = malaysianNumber.replace(/[\s-]/g, '').replace(/^0/, '');
  return `+60${cleaned}`;
}

function fromE164(e164Number) {
    // Extract the national number
    const nationalNumber = e164Number.replace(/^\+60/, '');

    // Mobile numbers (01X prefix)
    if (nationalNumber.startsWith('1')) {
        const prefix = nationalNumber.slice(0, 2);
        // 011 and 015 have 8-digit subscriber numbers
        if (prefix === '11' || prefix === '15') {
            return `0${nationalNumber.slice(0, 2)}-${nationalNumber.slice(2)}`;
        }
        // Other 01X prefixes have 7-digit subscriber numbers
        return `0${nationalNumber.slice(0, 2)}-${nationalNumber.slice(2)}`;
    }
    // Landline numbers
    else if (nationalNumber.startsWith('3')) {
        // Area code 3 (Kuala Lumpur, Selangor, Putrajaya) has 8-digit subscriber numbers
        return `0${nationalNumber.slice(0, 1)}-${nationalNumber.slice(1)}`;
    }
    else if (nationalNumber.startsWith('8')) {
        // East Malaysia (two-digit area codes, 6-digit subscriber numbers)
        return `0${nationalNumber.slice(0, 2)}-${nationalNumber.slice(2)}`;
    }
    else {
        // Other Peninsular Malaysia area codes (7-digit subscriber numbers)
        return `0${nationalNumber.slice(0, 1)}-${nationalNumber.slice(1)}`;
    }
}

Validation Best Practices

  • Regex Validation: Use regex patterns to enforce the correct format.
  • Length Checks: Verify the number of digits after removing formatting characters.
  • Area Code/Prefix Validation: Cross-reference area codes and prefixes against official MCMC lists.
  • Carrier Lookup (for Mobile): If precise routing is required, integrate a carrier lookup API.
  • Input Sanitization: Always strip spaces, hyphens, and other formatting before validation to handle user input variations.
  • Error Handling: Provide clear error messages indicating which part of the phone number is invalid (e.g., "Invalid area code" vs. "Invalid number length").
  • Security Considerations:
    • Never expose phone numbers in URLs or logs without proper encryption
    • Implement rate limiting on validation endpoints to prevent enumeration attacks
    • Use HTTPS for all API calls involving phone number data
    • Consider implementing phone number verification via SMS OTP before allowing account creation or sensitive operations
    • Hash or tokenize phone numbers in non-production environments
    • Apply proper access controls and audit logging for phone number lookups

How to Format Malaysian Phone Numbers for WhatsApp

When adding Malaysian contacts to WhatsApp or sending WhatsApp messages programmatically, use E.164 format without spaces or special characters:

  • Correct WhatsApp Format: +60123456789 (for mobile 012-3456789)
  • Alternative Format: 60123456789 (WhatsApp accepts numbers with or without the + prefix)
  • Example for Business API: When using WhatsApp Business API or SMS API integrations, format all Malaysian numbers as +60 followed by the digits after the leading 0.

WhatsApp Number Formatting Examples:

Local FormatWhatsApp FormatDescription
012-3456789+60123456789Maxis mobile
011-12345678+6011112345678U Mobile (8-digit subscriber)
03-87654321+60387654321KL landline (works for WhatsApp calls)

What Are the Best Practices for Storing and Displaying Malaysian Phone Numbers?

  • Storage: Store numbers in E.164 format for consistency and efficient querying. You can store the original format as a separate field if needed.
  • Display: Format numbers according to local conventions for user-friendliness. Use international format when appropriate (e.g., for international contacts).

Database Schema Recommendations

When storing Malaysian phone numbers in a database, consider this schema:

sql
CREATE TABLE contacts (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    phone_e164 VARCHAR(15) NOT NULL,  -- E.164 format: +60XXXXXXXXXX
    phone_display VARCHAR(20),          -- Local format: 0XX-XXXXXXXX
    phone_type ENUM('mobile', 'landline', 'toll-free', 'premium', 'other'),
    carrier VARCHAR(50),                -- Original carrier (pre-MNP)
    country_code CHAR(2) DEFAULT 'MY',
    verified_at TIMESTAMP,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_phone_e164 (phone_e164),
    INDEX idx_phone_type (phone_type)
);

Key considerations:

  • Use phone_e164 as the primary searchable field with an index
  • Store phone_display for presenting to users in local format
  • Include phone_type for routing and business logic
  • Track verified_at to know which numbers have been confirmed via SMS OTP
  • Use VARCHAR(15) for E.164 as the maximum length is 15 digits per ITU-T E.164 standard

Data Migration from Legacy Formats

If migrating from legacy systems with various formats:

python
def migrate_malaysian_phone_number(legacy_number):
    """Convert legacy phone number formats to E.164."""
    import re

    # Remove all non-digit characters except +
    cleaned = re.sub(r'[^\d+]', '', legacy_number)

    # Already in E.164 format
    if cleaned.startswith('+60'):
        return cleaned

    # Has country code but no +
    if cleaned.startswith('60'):
        return '+' + cleaned

    # Local format with leading 0
    if cleaned.startswith('0') and len(cleaned) >= 9:
        return '+60' + cleaned[1:]

    # No leading 0 (malformed)
    if len(cleaned) >= 8 and not cleaned.startswith('0'):
        return '+60' + cleaned

    # Invalid format
    raise ValueError(f"Cannot parse phone number: {legacy_number}")

# Usage
legacy_numbers = ["03-87654321", "60387654321", "012-3456789", "0166543210"]
for num in legacy_numbers:
    try:
        print(f"{num} -> {migrate_malaysian_phone_number(num)}")
    except ValueError as e:
        print(f"Error: {e}")

What Is Malaysia's 5G Network Coverage in 2025?

Malaysia transitioned from a single wholesale 5G network to a dual 5G network model (effective December 31, 2024, per Ministerial Direction No. 4 of 2024). Digital Nasional Berhad (DNB), wholly owned by the Minister of Finance, operates the first 5G network, while U Mobile operates the second 5G network.

5G Advanced Technology: In February 2025, DNB and Ericsson launched 5G Advanced technology on DNB's network, leveraging AI to enhance user experience with ultra-low latency and high throughput. DNB delivers a minimum download speed of 100 Mbps across the network, with an average 5G speed of 240 Mbps.

Coverage Targets: The state government, in collaboration with MCMC, is working to achieve 100% 5G network coverage across Selangor by 2025. 4G coverage is extensive, reaching over 95% of populated areas, including rural regions.

Find coverage maps and speed test data from resources like nPerf, DNB's interactive coverage map (digital-nasional.com.my/interactive-map), and operator websites (e.g., Maxis, CelcomDigi, U Mobile). This information is valuable for developers building location-aware applications or services that rely on network connectivity.

Frequently Asked Questions About Malaysian Phone Numbers

What is the country code for Malaysia?

Malaysia's country code is +60. Add this prefix before the national number when calling from outside Malaysia, and remove the leading 0 from the domestic number.

How many digits are in a Malaysian mobile number?

Malaysian mobile numbers have either 10 or 11 digits total (including the leading 0). Prefixes 011 and 015 have 8-digit subscriber numbers (11 digits total), while all other mobile prefixes have 7-digit subscriber numbers (10 digits total).

How do I format a Malaysia phone number for WhatsApp?

Format Malaysian numbers in E.164 format for WhatsApp: +60123456789 (remove the leading 0 and add +60). WhatsApp also accepts numbers without the + prefix, e.g., 60123456789.

What is the emergency number in Malaysia?

The emergency number in Malaysia is 999, which connects you to police, fire, and ambulance services. You can also dial 112, the international emergency number.

How do I validate a Malaysian phone number?

Use regex patterns to validate format: ^0[3-9]-\d{7,8}$ for landlines and ^01[0-9]-\d{7,8}$ for mobile numbers. Verify area codes against official MCMC lists and check digit length after removing formatting characters. For production applications, consider using libraries like Python's phonenumbers or validation APIs.

What is Mobile Number Portability (MNP) in Malaysia?

MNP allows customers to switch mobile providers while keeping their phone number. Implemented on October 1, 2008, Malaysia's MNP service currently has a high rejection rate (over 50%), significantly above the global best practice of below 10%.

What are the main mobile carriers in Malaysia?

The main mobile carriers are Maxis (prefixes 012, 017), Celcom (010, 013, 019), DiGi (016), and U Mobile (018). However, due to Mobile Number Portability, prefixes no longer guarantee which carrier currently serves a number.

Which area code is used for Kuala Lumpur?

Kuala Lumpur uses area code 03, which also covers Putrajaya and parts of Selangor. Landlines in this area have 8-digit subscriber numbers.

What format should I use to store Malaysian phone numbers in a database?

Store phone numbers in E.164 format (+60XXXXXXXXXX) for consistency, international compatibility, and efficient querying. You can store the original format as a separate field if needed for display purposes.

Are toll-free numbers really free in Malaysia?

1800 numbers are free when called from landlines but are charged at local rates when called from mobile phones. Check with your carrier for specific rates.

What is the IRBM e-invoice phone number requirement?

As of April 12, 2025, Malaysia's IRBM requires all phone numbers in e-invoices to be in strict E.164 format: starting with +, followed by country code +60, with no spaces, hyphens, or parentheses (e.g., +60123456789).

What validation libraries support Malaysian phone numbers?

Several libraries support Malaysian phone numbers including Google's libphonenumber (available for Java, JavaScript, Python, C++), and commercial APIs like Abstract's Phone Validation API and Twilio Lookup.

Keeping Up-to-Date

The telecommunications landscape is constantly evolving. Refer to the MCMC website and the official Numbering and Electronic Addressing Plan (NEAP) for the latest regulations and numbering plan updates. The NEAP is published by MCMC and covers telecommunications numbering, including sub-section 13 on Domain Names.

Key Resources:

  • MCMC Official Site: mcmc.gov.my – Primary regulatory authority
  • NEAP Documentation: Available at mynic.my/neap
  • Operator Websites: Check Maxis, CelcomDigi, DiGi, U Mobile, and other carriers for prefix allocations and service updates
  • Wikipedia Reference: Telephone numbers in Malaysia – Community-maintained resource with historical context

Change Management Best Practices:

  • Monitor MCMC announcements for new prefix allocations or format changes
  • Implement a configurable validation system that can be updated without code deployment
  • Maintain a separate configuration file or database table for area codes and prefixes
  • Set up alerts for validation failures that may indicate new number formats
  • Review and update validation rules quarterly to catch new MVNO prefixes
  • Subscribe to MCMC's mailing list or RSS feeds for regulatory updates
  • Test your validation logic against real-world numbers periodically