Rackspace Email Troubleshooting
This guide covers common issues, error messages, and solutions for the Rackspace Email integration.
Common Issues
Authentication Errors
Invalid API Credentials (401 Unauthorized)
Symptoms:
- HTTP 401 errors from Rackspace API
- "Invalid API credentials" error messages
- All Rackspace API calls failing
Causes:
- Incorrect API Key or Secret Key
- Wrong Customer ID
- Expired or revoked API credentials
- Extra whitespace in environment variables
Solutions:
-
Verify Environment Variables
# Check that variables are set echo $RACKSPACE_API_KEY echo $RACKSPACE_SECRET_KEY echo $RACKSPACE_CUSTOMER_ID -
Check for Extra Whitespace
# Remove any trailing spaces or newlines export RACKSPACE_API_KEY="$(echo $RACKSPACE_API_KEY | tr -d '[:space:]')" export RACKSPACE_SECRET_KEY="$(echo $RACKSPACE_SECRET_KEY | tr -d '[:space:]')" -
Regenerate API Credentials
- Login to Rackspace Email Admin Panel
- Navigate to My Account > API Keys
- Revoke old key and generate new one
- Update environment variables with new credentials
-
Test API Connection
// test-rackspace-auth.js const RackspaceClient = require('./sync/rackspace/lib/client'); const client = new RackspaceClient({ apiKey: process.env.RACKSPACE_API_KEY, secretKey: process.env.RACKSPACE_SECRET_KEY, customerId: process.env.RACKSPACE_CUSTOMER_ID }); client.checkMailboxExists('test@natca.net') .then(() => console.log('✅ Authentication successful')) .catch(err => console.error('❌ Authentication failed:', err.message));
Signature Verification Failed
Symptoms:
- "Invalid signature" error from Rackspace API
- Authentication fails despite correct credentials
Causes:
- Incorrect timestamp format (must be Unix timestamp in seconds)
- Wrong User-Agent string
- Signature calculation error
- Clock synchronization issues
Solutions:
-
Verify Timestamp Format
// Correct: Unix timestamp in seconds const timestamp = Math.floor(Date.now() / 1000).toString(); // Incorrect: milliseconds const badTimestamp = Date.now().toString(); // Don't use this -
Check User-Agent String
// Must match exactly const userAgent = 'MyNATCA Platform'; // Correct -
Verify Signature Calculation
const crypto = require('crypto'); // Correct order: apiKey + userAgent + timestamp + secretKey const dataToSign = apiKey + userAgent + timestamp + secretKey; const signature = crypto.createHash('sha1').update(dataToSign).digest('hex'); console.log('Data to sign:', dataToSign); console.log('Signature:', signature); console.log('Header:', `${apiKey}:${timestamp}:${signature}`); -
Check Server Time Synchronization
# Verify server time is accurate date # If time is wrong, synchronize with NTP sudo ntpdate -s time.nist.gov
Email Creation Errors
Email Already Exists
Symptoms:
- "Email address already exists" error
- Creation fails even though availability check passed
Causes:
- Race condition (another request created the email)
- Email was created outside the platform
- Cache/timing issue between availability check and creation
Solutions:
-
Check Email in Rackspace Admin Panel
- Login to https://admin.emailsrvr.com (opens in a new tab)
- Navigate to Email Accounts > Rackspace Email
- Search for the email address
- Verify if it exists and who owns it
-
Try Alternative Email Format
// If jdoss@natca.net exists, try jason.doss@natca.net const formats = [ `${firstName.charAt(0)}${lastName}@natca.net`, `${firstName}.${lastName}@natca.net`, `${firstName.charAt(0)}${lastName}2@natca.net` // Add number if needed ]; -
Manual Cleanup If email exists but shouldn't:
- Delete mailbox in Rackspace Admin Panel
- Remove from emailinformation table in MySQL
- Retry creation
Member Already Has NATCA Email
Symptoms:
- "Member already has a @natca.net email" error
- User reports they don't have an email but system says they do
Causes:
- Email exists in database but not in Rackspace
- Previous email creation failed partially
- Database record not cleaned up after email deletion
Solutions:
-
Check Database Record
SELECT emailaddress, emailtypeid, isactive, createddate FROM emailinformation WHERE membernumber = '12345' AND emailaddress LIKE '%@natca.net'; -
Verify Email in Rackspace
const exists = await rackspaceClient.checkMailboxExists(email); console.log('Email exists in Rackspace:', exists); -
Cleanup Orphaned Records
-- If email doesn't exist in Rackspace, remove database record DELETE FROM emailinformation WHERE membernumber = '12345' AND emailaddress = 'jdoss@natca.net' AND emailaddress NOT IN (SELECT email FROM rackspace_verified_emails); -
Or Mark as Inactive
-- Safer option: mark as inactive instead of deleting UPDATE emailinformation SET isactive = 0 WHERE membernumber = '12345' AND emailaddress = 'jdoss@natca.net';
Member Not Eligible
Symptoms:
- "Only NATCA members are eligible" error
- "Only Active or Retired members can receive @natca.net emails" error
Causes:
- Member is not membertypeid=6 (NATCA member)
- Member status is not Active or Retired
- Member data is outdated
Solutions:
-
Verify Member Type
SELECT membernumber, firstname, lastname, membertypeid, status FROM members WHERE membernumber = '12345'; -
Check Member Type Mapping
// membertypeid values: // 6 = NATCA member (eligible) // Other values = ineligible if (member.membertypeid !== 6) { console.log('Member type:', member.membertypeid, '- Not NATCA'); } -
Verify Member Status
-- Eligible statuses SELECT * FROM members WHERE membernumber = '12345' AND status IN ('Active', 'Retired'); -
Update Member Data If member data is outdated:
- Trigger member sync from source system
- Verify sync completed successfully
- Retry email creation
Password Reset Errors
Email Not Found
Symptoms:
- "Email not found or does not belong to this member" error
- Password reset fails for valid email
Causes:
- Email not in emailinformation table
- Email belongs to different member
- Typo in email address
Solutions:
-
Verify Email Ownership
SELECT membernumber, emailaddress FROM emailinformation WHERE emailaddress = 'jdoss@natca.net'; -
Check Rackspace
const exists = await rackspaceClient.checkMailboxExists('jdoss@natca.net'); if (!exists) { console.log('Email does not exist in Rackspace'); } -
Verify Member Number Match
// Ensure member owns the email const [records] = await pool.query( 'SELECT * FROM emailinformation WHERE membernumber = ? AND emailaddress = ?', [memberNumber, email] ); if (records.length === 0) { console.log('Email does not belong to member', memberNumber); }
Password Doesn't Meet Requirements
Symptoms:
- "Password does not meet requirements" error from Rackspace
- Password reset fails despite using generated password
Causes:
- Password generator bug
- Rackspace requirements changed
- Password too short or missing character types
Solutions:
-
Verify Password Requirements
function validatePassword(password) { const hasUppercase = /[A-Z]/.test(password); const hasLowercase = /[a-z]/.test(password); const hasNumber = /[0-9]/.test(password); const hasSpecial = /[!@#$%^&*]/.test(password); const typesPresent = [hasUppercase, hasLowercase, hasNumber, hasSpecial] .filter(Boolean).length; return password.length >= 8 && typesPresent >= 3; } -
Test Password Generator
const password = rackspaceClient.generatePassword(); console.log('Generated password:', password); console.log('Length:', password.length); console.log('Valid:', validatePassword(password)); -
Update Password Generator If requirements changed, update generator in
/sync/rackspace/lib/client.js
Database Errors
Failed to Update Member Profile
Symptoms:
- Email created in Rackspace but not added to database
- "Failed to update member profile" error
Causes:
- MySQL connection failure
- Database permissions issue
- Duplicate key constraint violation
- Table doesn't exist
Solutions:
-
Verify Database Connection
try { const [rows] = await pool.query('SELECT 1'); console.log('✅ MySQL connection successful'); } catch (error) { console.error('❌ MySQL connection failed:', error.message); } -
Check Table Exists
SHOW TABLES LIKE 'emailinformation'; -
Verify Permissions
SHOW GRANTS FOR 'your_mysql_user'@'%'; -- Should include INSERT, UPDATE, SELECT on emailinformation table -
Manual Record Creation If automatic insertion fails:
INSERT INTO emailinformation (membernumber, emailaddress, emailtypeid, isactive) VALUES ('12345', 'jdoss@natca.net', 3, 1); -
Cleanup on Failure If database insertion fails after Rackspace creation:
try { // Create in Rackspace await rackspaceClient.createMailbox(mailboxData); // Add to database await pool.query(insertQuery, values); } catch (error) { // Rollback: delete from Rackspace if database failed await rackspaceClient.deleteMailbox(emailAddress); throw error; }
Rate Limiting
Too Many Requests (429)
Symptoms:
- HTTP 429 errors from Rackspace API
- "Rate limit exceeded" messages
- Intermittent failures during batch operations
Causes:
- Exceeded Rackspace API rate limits (60 req/min)
- Multiple concurrent requests
- Retry loops without delays
Solutions:
-
Implement Exponential Backoff
async makeRequestWithRetry(url, options, maxRetries = 3) { for (let attempt = 1; attempt <= maxRetries; attempt++) { try { const response = await fetch(url, options); if (response.status === 429) { const retryAfter = response.headers.get('Retry-After') || 60; console.log(`Rate limited, waiting ${retryAfter}s...`); await this.sleep(retryAfter * 1000); continue; } return response; } catch (error) { if (attempt === maxRetries) throw error; await this.sleep(Math.pow(2, attempt) * 1000); } } } -
Add Request Queuing
const queue = []; const RATE_LIMIT = 60; // requests per minute const INTERVAL = 60000 / RATE_LIMIT; // ms between requests async function queueRequest(requestFn) { queue.push(requestFn); if (queue.length === 1) { await processQueue(); } } async function processQueue() { while (queue.length > 0) { const requestFn = queue.shift(); await requestFn(); await sleep(INTERVAL); } } -
Monitor Rate Limits
logger.info('Rackspace API request', { endpoint: url, rateLimitRemaining: response.headers.get('X-RateLimit-Remaining'), rateLimitReset: response.headers.get('X-RateLimit-Reset') });
Debugging Tools
Enable Debug Logging
// In Rackspace client
const DEBUG = process.env.RACKSPACE_DEBUG === 'true';
function debugLog(message, data) {
if (DEBUG) {
console.log('[Rackspace Debug]', message, JSON.stringify(data, null, 2));
}
}
// Usage
debugLog('Making request', { url, headers: { ...headers, 'X-Api-Signature': '***' } });Test Individual Methods
// test-rackspace-methods.js
const RackspaceClient = require('./sync/rackspace/lib/client');
const client = new RackspaceClient({
apiKey: process.env.RACKSPACE_API_KEY,
secretKey: process.env.RACKSPACE_SECRET_KEY,
customerId: process.env.RACKSPACE_CUSTOMER_ID
});
async function testMethods() {
try {
// Test 1: Check mailbox exists
console.log('Test 1: Check mailbox exists');
const exists = await client.checkMailboxExists('test@natca.net');
console.log('Result:', exists);
// Test 2: Generate password
console.log('\nTest 2: Generate password');
const password = client.generatePassword();
console.log('Password:', password);
console.log('Length:', password.length);
// Test 3: Create mailbox (use test account)
console.log('\nTest 3: Create mailbox');
const result = await client.createMailbox({
emailAddress: 'test123@natca.net',
password: password,
displayName: 'Test User',
firstName: 'Test',
lastName: 'User'
});
console.log('Created:', result);
// Test 4: Reset password
console.log('\nTest 4: Reset password');
const newPassword = client.generatePassword();
await client.resetPassword('test123@natca.net', newPassword);
console.log('Password reset successful');
} catch (error) {
console.error('Test failed:', error.message);
console.error('Stack:', error.stack);
}
}
testMethods();Verify API Signature
// verify-signature.js
const crypto = require('crypto');
function verifySignature(apiKey, secretKey, userAgent, timestamp) {
const dataToSign = apiKey + userAgent + timestamp + secretKey;
const signature = crypto.createHash('sha1').update(dataToSign).digest('hex');
const header = `${apiKey}:${timestamp}:${signature}`;
console.log('=== Signature Verification ===');
console.log('API Key:', apiKey);
console.log('User Agent:', userAgent);
console.log('Timestamp:', timestamp);
console.log('Secret Key:', '***' + secretKey.slice(-4));
console.log('Data to sign:', dataToSign.replace(secretKey, '***'));
console.log('SHA1 signature:', signature);
console.log('X-Api-Signature header:', header);
}
// Usage
verifySignature(
process.env.RACKSPACE_API_KEY,
process.env.RACKSPACE_SECRET_KEY,
'MyNATCA Platform',
Math.floor(Date.now() / 1000).toString()
);Check Database State
-- View all NATCA emails
SELECT membernumber, emailaddress, emailtypeid, isactive, createddate
FROM emailinformation
WHERE emailaddress LIKE '%@natca.net'
ORDER BY createddate DESC;
-- Count NATCA emails by status
SELECT isactive, COUNT(*) as count
FROM emailinformation
WHERE emailaddress LIKE '%@natca.net'
GROUP BY isactive;
-- Find members with multiple NATCA emails (should be none)
SELECT membernumber, COUNT(*) as email_count
FROM emailinformation
WHERE emailaddress LIKE '%@natca.net' AND isactive = 1
GROUP BY membernumber
HAVING COUNT(*) > 1;
-- Check for orphaned records (email in DB but not in Rackspace)
-- Run this with a script that checks Rackspace API
SELECT emailaddress
FROM emailinformation
WHERE emailaddress LIKE '%@natca.net' AND isactive = 1;Error Messages Reference
Platform API Errors
| Error Message | HTTP Code | Cause | Solution |
|---|---|---|---|
| Authentication required | 401 | No Auth0 session | Login via Auth0 |
| Member not found | 404 | Invalid member number | Verify member exists |
| Only NATCA members are eligible | 400 | membertypeid != 6 | Member must be NATCA |
| Only Active or Retired members | 400 | Invalid status | Check member status |
| Member already has email | 400 | Existing NATCA email | Use password reset instead |
| Invalid email format | 400 | Email doesn't end with @natca.net | Use correct domain |
| Email address already exists | 400 | Mailbox exists in Rackspace | Try alternative format |
| Failed to create email account | 500 | Rackspace API error | Check logs and retry |
| Failed to update member profile | 500 | Database error | Check MySQL connection |
Rackspace API Errors
| Error Message | HTTP Code | Cause | Solution |
|---|---|---|---|
| Invalid API credentials | 401 | Wrong API key/secret | Verify credentials |
| Invalid signature | 401 | Signature calculation error | Check timestamp and hash |
| Mailbox not found | 404 | Email doesn't exist | Verify email address |
| Mailbox already exists | 409 | Duplicate creation | Email is taken |
| Password does not meet requirements | 400 | Weak password | Use password generator |
| Rate limit exceeded | 429 | Too many requests | Implement backoff |
| Mailbox quota exceeded | 403 | Account limit reached | Contact Rackspace |
| Domain not found | 404 | Wrong customer ID | Verify customer ID |
Getting Help
Logs to Collect
When reporting issues, include:
-
Platform Logs
# View recent Rackspace-related logs grep "rackspace" /var/log/platform/platform.log | tail -50 -
Error Details
- Full error message
- HTTP status code
- Request parameters (redact sensitive data)
- Timestamp of failure
-
Environment Information
- Platform version
- Node.js version
- Deployment environment (local/staging/production)
-
Member Information
- Member number
- Member type ID
- Member status
- Existing emails in database
Escalation Path
- Check This Troubleshooting Guide
- Review Platform Logs
- Test Individual Components (API, database, Rackspace)
- Contact Platform Team with logs and error details
- Contact Rackspace Support if API issue confirmed
Related Documentation
This troubleshooting guide helps diagnose and resolve common Rackspace Email integration issues quickly and efficiently.