Flask Python Web (CGI): "Alert Internal Error"


I’m trying to set up my Flask python app on Caddy, with my own domain. I used to run the website on grandpa Apache2 until someone told me about Caddy. I had a letsencrypt certificate for apache, which I have since certbot delete'd.

I’ve been attempting to follow this guide, which uses cgi.

I run Caddy by using caddy -conf <Caddyfile_path> and the Caddy output looks good I think (swapped my actual domain with domain.com below):

2020/05/05 11:01:11 [INFO] [www.domain.com] Server responded with a certificate.

Serving HTTPS on port 443 

Serving HTTP on port 80 

WARNING: File descriptor limit 1024 is too low for production servers. At least 8192 is recommended. Fix with `ulimit -n 8192`.

However, unfortunately:

This is me curling the website from another machine:

curl https://domain.com
curl: (35) error:14094438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error

And here is what happens if I curl from the website host machine:

curl localhost:443
Client sent an HTTP request to an HTTPS server.

Here is my Caddyfile:

www.domain.com {
        cgi / /root/Web/server.cgi
        log /root/Web/logs/access.log
        errors /root/Web/errors.log

My python script is titled server.py and works perfectly fine on Flask. I’ve followed that guide I linked to at the top to the T. My server.cgi file looks exactly identical to the one provided in the guide, as well (where yourapplication in my case is server).
Thank you for the help.

that article is caddy 1 and current version is caddy 2.

can you please try with

domain.com {

instead of www

Ah woops that’s right.
Just tried curling, and now getting:

curl domain.com
<a href="https://domain.com/">Moved Permanently</a>.

It seems I’m now getting a redirection error.

EDIT: huh I’m now getting the follow

curl -i https://domain.com
HTTP/2 308 
content-type: text/html; charset=utf-8
location: https://domain.com/
server: Caddy
content-length: 251
date: Tue, 05 May 2020 11:54:05 GMT

<p>You should be redirected automatically to target URL: <a href="https://domain.com/">https://domain.com/</a>.  If not click the link.

Oh, okay I think I have a better sense of the problem.

I can actually access all of the other pages on my website (e.g. domain.com/join, domain.com/explore, etc.) – the only page giving me trouble seems to be the home page, whose location is /

Here are relevant portions of my main python file if this helps:

from flask import Flask
from flask import render_template
from flask import Response, request, jsonify
app = Flask(__name__)

def mission(name=None):

    return render_template('mission.html')

if __name__ == '__main__':
   app.run(debug = True)

I’m not sure why the main page gives the redirection error…

domain.com {
cgi /root/Web/server.cgi
log /root/Web/logs/access.log
errors /root/Web/errors.log


domain.com {
cgi * /root/Web/server.cgi
log /root/Web/logs/access.log
errors /root/Web/errors.log

The first block, without the *, gave me:

Activating privacy features... done.
2020/05/05 13:07:55 expecting at least 2 arguments for simple directive, got 1

The second block is giving me “404 Not found” on all pages, including the ones that seemed to work previously.

if i were you, i would use Gunicorn, uwsgi etc. to serve my application and then just reverse_proxy with Caddy 2.

Yeah I think that’s probably the best move. I hadn’t much realized that the guide I was following was modeled on Caddy v1, and not v2.
If by any chance you have any helpful links/examples, do please send them – mostly I’ve found this, although I believe I’d tried and was still getting any issues: examples/flask at master · caddyserver/examples · GitHub

Thanks for all the help!

Install UWSGI first.

Installing uWSGI — uWSGI 2.0 documentation

Then run your application with

uwsgi --http --module myproject:app

Your Caddy 2 config will be

domain.com {


I set everything up (even as a systemd service yay) and things are looking good now, thank you again.
Follow up question, what would be best practice on how to start up the uwsgi every time? Should I just have the command in a bash script somewhere / running in its own screen? Is there any way to automate that, or even to have caddy run the command if it senses it’s being enabled?

well, it’s not the best practice but i am using screen in linux for development purposes.

just type screen, then run your application and close the ssh. :smiley:

1 Like

I’m trying to run this in prod haha but hey as long as it works right^^
Thank you again for the help :pray:
Had not realized my problem was a version one in part.

you will want to use linux services.

actually i don’t know how to create one :smiley:

ExecStart=uwsgi smtg...

I guess something like that…

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.