Angular Works Locally but Cannot Call the Production Web API — What Would You Check?
This is a common Angular + ASP.NET Core production troubleshooting scenario.
The most important areas to check are:
Angular Production Build
↓
Production API URL
↓
HTTPS / DNS / Network
↓
CORS
↓
Authentication / JWT
↓
Reverse Proxy / IIS / Gateway
↓
ASP.NET Core API
↓
Logs
1. What Does the Problem Mean?
Suppose everything works locally:
Angular
http://localhost:4200
↓
ASP.NET Core API
https://localhost:7001
But after deployment:
Angular
https://www.myapp.com
↓
ASP.NET Core API
https://api.myapp.com
↓
Fails
This usually means the Angular code itself is not necessarily the problem. Something is different between the development and production environments.
Common causes include:
- Wrong production API URL
- CORS configuration
- HTTP/HTTPS mixed content
- DNS problems
- Firewall/network restrictions
- Invalid SSL certificate
- JWT issuer/audience mismatch
- Reverse proxy/IIS routing
- Incorrect environment configuration
- API unavailable
- Authentication header missing
2. First Check — Browser Network Tab
My first step would be:
F12
↓
Network
↓
Trigger API request
↓
Select failed request
Check:
Request URL
Status Code
Request Headers
Response Headers
Response Body
Console errors
For example, verify that Angular is actually calling:
https://api.myapp.com/api/products
and not accidentally calling:
http://localhost:7001/api/products
This immediately identifies many production configuration problems.
3. Check the Production API URL
This is one of the most common issues.
During development:
export const environment = {
production: false,
apiUrl: 'https://localhost:7001/api'
};
Production should use the deployed API:
export const environment = {
production: true,
apiUrl: 'https://api.myapp.com/api'
};
Then:
@Injectable({
providedIn: 'root'
})
export class ProductService {
private apiUrl =
`${environment.apiUrl}/products`;
constructor(private http: HttpClient) {}
getProducts() {
return this.http.get<Product[]>(
this.apiUrl
);
}
}
Production should never accidentally contain:
localhost
because in the user's browser, localhost means the user's own machine, not your production server.
4. Check the Angular Production Build Configuration
Suppose you have:
src/environments/environment.ts
src/environments/environment.production.ts
environment.ts
export const environment = {
production: false,
apiUrl: 'https://localhost:7001/api'
};
environment.production.ts
export const environment = {
production: true,
apiUrl: 'https://api.myapp.com/api'
};
Your production build configuration must use the intended environment configuration.
Then build:
ng build --configuration production
A key troubleshooting question is:
Which API URL actually ended up in the deployed JavaScript bundle?
Don't assume the production configuration was selected correctly—verify the request URL in the browser.
5. Check CORS
Suppose Angular is deployed at:
https://www.myapp.com
and API at:
https://api.myapp.com
These are different origins.
ASP.NET Core must allow the Angular origin.
Program.cs
builder.Services.AddCors(options =>
{
options.AddPolicy("AngularProduction", policy =>
{
policy
.WithOrigins(
"https://www.myapp.com"
)
.AllowAnyHeader()
.AllowAnyMethod();
});
});
Then:
app.UseCors("AngularProduction");
app.UseAuthentication();
app.UseAuthorization();
6. Origin Must Match Exactly
This is important.
Suppose ASP.NET Core allows:
.WithOrigins(
"https://myapp.com"
)
but Angular actually runs from:
https://www.myapp.com
These are different origins.
Likewise:
http://myapp.com
and:
https://myapp.com
are different origins.
An origin consists of:
scheme + host + port
For example:
https://www.myapp.com:443
7. Check the Browser Console for CORS Errors
Open:
F12
↓
Console
You may see an error indicating that a request from your frontend origin was blocked by the CORS policy.
If so, fix CORS on the ASP.NET Core server.
Don't try to solve production CORS by changing Angular code.
8. Check the Preflight OPTIONS Request
Some browser requests cause a CORS preflight.
For example:
OPTIONS /api/products
The browser is effectively asking:
Can https://www.myapp.com
call this API using this method/header combination?
If the OPTIONS request fails, the browser may never send the actual API request.
In the Network tab, check:
OPTIONS /api/products
If that fails, investigate CORS, proxy, authentication, and web-server handling of OPTIONS.
9. Check HTTPS / Mixed Content
Suppose Angular uses:
https://www.myapp.com
but the API is:
http://api.myapp.com
The page is secure but attempts to call an insecure HTTP resource.
Browsers can block this as mixed content.
Use:
https://www.myapp.com
↓
https://api.myapp.com
rather than:
https://www.myapp.com
↓
http://api.myapp.com
10. Check the SSL/TLS Certificate
Try opening the production API directly:
https://api.myapp.com/swagger
or an appropriate public health endpoint.
If the browser reports certificate problems, investigate:
- Expired certificate
- Wrong hostname
- Incomplete certificate chain
- Untrusted certificate
- Incorrect server configuration
A certificate valid for:
www.myapp.com
is not automatically valid for:
api.myapp.com
unless the certificate includes that hostname or uses an appropriate wildcard.
11. Check Whether the API Is Actually Running
Don't assume the API is healthy simply because Angular deployed successfully.
Test the production API independently using:
- Browser for public GET endpoints
- Swagger
- Postman
curl- Health-check endpoint
For example:
curl https://api.myapp.com/health
A simple ASP.NET Core health check could be:
builder.Services.AddHealthChecks();
and:
app.MapHealthChecks("/health");
Then test:
https://api.myapp.com/health
Expected:
Healthy
12. Test Without Angular
This is one of the best troubleshooting techniques.
Angular fails
↓
Take exact production API URL
↓
Test using Postman / Swagger
If Postman also fails
Investigate:
API deployment
DNS
SSL
Authentication
Firewall
Reverse proxy
Server configuration
If Postman works but browser Angular fails
Investigate:
CORS
Preflight
Angular API URL
Authorization header
Browser mixed-content restrictions
Cookie/credential behavior
Remember that Postman is not subject to browser CORS enforcement, so Postman working does not prove CORS is configured correctly.
13. Check JWT Authentication
Suppose the API returns:
401 Unauthorized
Check whether Angular sends:
Authorization: Bearer eyJhbGciOi...
Open:
F12
→ Network
→ Request
→ Request Headers
Look for:
Authorization: Bearer <token>
If missing, check your interceptor.
export const authInterceptor: HttpInterceptorFn =
(req, next) => {
const token =
localStorage.getItem('access_token');
if (!token) {
return next(req);
}
const authRequest = req.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
return next(authRequest);
};
14. Check Production JWT Configuration
Local configuration might contain:
{
"Jwt": {
"Issuer": "MyApi",
"Audience": "MyAngularApp"
}
}
But production might have different configuration through:
appsettings.json
appsettings.Production.json
Environment variables
Azure configuration
Key Vault
Check that token generation and validation agree on:
Issuer
Audience
Signing key
Token lifetime
Authentication scheme
For example:
options.TokenValidationParameters =
new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer =
configuration["Jwt:Issuer"],
ValidAudience =
configuration["Jwt:Audience"]
};
A production-only configuration mismatch can result in:
401
even when local authentication works perfectly.
15. Check Firewall and Network Rules
Production environments often have restrictions that local environments don't.
For example:
Internet
↓
Firewall
↓
Load Balancer
↓
IIS / Nginx
↓
ASP.NET Core
Check:
- Is port
443open? - Is the API publicly reachable if it should be?
- Is an IP allowlist blocking requests?
- Is a cloud Network Security Group blocking traffic?
- Is a Web Application Firewall rejecting requests?
- Is the API intended to be private-only?
16. Check DNS
Verify:
api.myapp.com
resolves to the correct production endpoint.
A deployment may be correct while DNS still points to:
Old Server
instead of:
New Server
Also consider DNS propagation after recent changes.
17. Check IIS / Nginx / Reverse Proxy
A production architecture might be:
Angular Browser
↓
https://api.myapp.com
↓
IIS / Nginx
↓
ASP.NET Core
The API itself may be running internally at:
http://localhost:5000
That's fine if the reverse proxy is configured correctly.
Check whether the proxy forwards:
/api/*
to the ASP.NET Core application.
A bad proxy rule can produce:
404
502
503
even though ASP.NET Core itself is healthy.
18. Understand the Status Code
The actual status code gives an important clue.
| Error | Investigate |
|---|---|
| CORS browser error | CORS / preflight |
400 |
Request payload/model binding |
401 |
JWT/authentication |
403 |
Authorization/roles/policies |
404 |
URL/routing/proxy |
405 |
HTTP method/proxy/CORS |
500 |
API exception |
502 |
Gateway/reverse proxy/upstream |
503 |
API/service unavailable |
| Certificate error | HTTPS/TLS |
| Mixed-content error | HTTPS frontend → HTTP API |
Don't start randomly changing configuration. Use the failure type to narrow the investigation.
19. Full Example Production Setup
Angular
https://www.myapp.com
ASP.NET Core
https://api.myapp.com
Angular environment
export const environment = {
production: true,
apiUrl: 'https://api.myapp.com/api'
};
Angular service
@Injectable({
providedIn: 'root'
})
export class ProductService {
constructor(private http: HttpClient) {}
getProducts() {
return this.http.get(
`${environment.apiUrl}/products`
);
}
}
ASP.NET Core CORS
builder.Services.AddCors(options =>
{
options.AddPolicy("Angular", policy =>
{
policy
.WithOrigins(
"https://www.myapp.com"
)
.AllowAnyHeader()
.AllowAnyMethod();
});
});
Pipeline
app.UseHttpsRedirection();
app.UseCors("Angular");
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
Result:
https://www.myapp.com
|
| GET
| https://api.myapp.com/api/products
|
| Authorization: Bearer <JWT>
v
ASP.NET Core
|
| CORS
| Authentication
| Authorization
v
ProductsController
20. Recommended Troubleshooting Flow
Use this sequence:
Angular production API call fails
↓
1. Open Browser Network tab
↓
2. Check exact Request URL
↓
3. Check status/error
↓
4. Check Console
↓
5. Test API directly
↓
6. Test API using Postman/Swagger
↓
7. Check HTTPS/certificate
↓
8. Check CORS/preflight
↓
9. Check Authorization header/JWT
↓
10. Check ASP.NET Core logs
↓
11. Check IIS/Nginx/Gateway
↓
12. Check DNS/firewall/network
Key Points
When Angular works locally but not against the production ASP.NET Core API, check these first:
- Correct production API URL
- Browser Network and Console errors
- CORS
- HTTPS and mixed content
- SSL certificate
- JWT/Authorization header
- Production ASP.NET Core configuration
- API availability
- DNS/firewall/network
- IIS/Nginx/reverse proxy
- Server-side logs
The most important diagnostic distinction is:
Postman also fails
↓
Likely API / infrastructure / authentication
Postman works
Angular browser fails
↓
Likely browser-specific issue:
CORS / preflight / mixed content /
Angular URL / headers / credentials
Interview Questions and Answers
1. Angular works locally but cannot call the production Web API. What would you check?
Interview Answer:
First, I would inspect the browser Network and Console tabs to identify the exact URL and error. Then I would verify the Angular production API URL, CORS, HTTPS/certificate configuration, authentication headers, and production API configuration. I would also test the API independently using Swagger or Postman and check server/reverse-proxy logs.
2. Why can Angular work locally but fail in production?
Because production introduces environment-specific differences such as:
API URL
CORS
HTTPS
Certificates
JWT configuration
DNS
Firewall
Reverse proxy
Environment variables
Local success does not guarantee those production dependencies are configured correctly.
3. Postman can call the production API, but Angular cannot. What would you suspect?
Answer:
I would first investigate browser-specific issues such as:
CORS
Preflight OPTIONS
Mixed content
Angular production URL
Authorization header
Cookie/credential configuration
Postman is not subject to browser CORS enforcement.
4. Angular gets 401 only in production. What would you check?
Check:
Authorization: Bearer <token>
and verify production JWT:
- issuer
- audience
- signing key
- expiration
- authentication scheme
Also confirm that the production interceptor is attaching the token.
5. Angular gets 404 from production API. What would you check?
Check the exact production URL, ASP.NET Core routes, deployment base path, and IIS/Nginx/reverse-proxy routing.
For example, Angular may call:
https://api.myapp.com/products
while the actual route is:
https://api.myapp.com/api/products
6. Angular gets 502 Bad Gateway. What does that suggest?
A 502 commonly indicates that a gateway or reverse proxy cannot successfully communicate with the upstream ASP.NET Core application.
Investigate:
IIS/Nginx/Gateway
↓
ASP.NET Core process
rather than starting with Angular component code.
7. Why can HTTPS Angular fail when calling an HTTP API?
Browsers can block an HTTPS page from making insecure HTTP requests due to mixed-content security rules.
Prefer:
HTTPS Angular
↓
HTTPS API
8. What is your first step when troubleshooting a production API failure?
Good interview answer:
My first step is the browser Network tab. I check the exact request URL, HTTP status, request headers, response, and any related Console error. That tells me whether to investigate Angular configuration, CORS, authentication, routing, or the production infrastructure.
This systematic approach is much stronger in an interview than saying “I would first check CORS”, because production connectivity failures can originate at several different layers.