[GH-ISSUE #508] Manual upload of recording fails on Ubuntu 20.04 #894

Closed
opened 2026-03-15 10:52:43 +03:00 by kerem · 8 comments
Owner

Originally created by @sskras on GitHub (Jun 23, 2022).
Original GitHub issue: https://github.com/asciinema/asciinema/issues/508

It works if I upload the small recording (195 bytes), but fails when I try to upload the 100 kB:
image

The curl session return HTTP/2 500 code and says "Internal Server Error":

$ curl -v -u sskras:$(cat ~/.config/asciinema/install-id) https://asciinema.org/api/asciicasts -F asciicast=@/tmp/tmpqsscy294-ascii.cast; echo
*   Trying 109.107.37.0:443...
* TCP_NODELAY set
* Connected to asciinema.org (109.107.37.0) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=*.asciinema.org
*  start date: May  8 10:34:01 2022 GMT
*  expire date: Aug  6 10:34:00 2022 GMT
*  subjectAltName: host "asciinema.org" matched cert's "asciinema.org"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Server auth using Basic with user 'sskras'
* Using Stream ID: 1 (easy handle 0x55d77a0d9090)
> POST /api/asciicasts HTTP/2
> Host: asciinema.org
> authorization: Basic c3NrcmFzOjE4MTI2MjVmLTE4ODktNDE2Ni04ZWY2LTcxNDlkODFhMzEzOQ==
> user-agent: curl/7.68.0
> accept: */*
> content-length: 102619
> content-type: multipart/form-data; boundary=------------------------2e0590fa72362da5
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
* We are completely uploaded and fine
< HTTP/2 500
< cache-control: max-age=0, private, must-revalidate
< content-type: text/plain; charset=utf-8
< date: Thu, 23 Jun 2022 09:37:24 GMT
< server: nginx
< x-request-id: Fvs2WRTm0Cq1it4EbE2i
< content-length: 21
<
* Connection #0 to host asciinema.org left intact
Internal Server Error

Any ideas on how to proceed?

Originally created by @sskras on GitHub (Jun 23, 2022). Original GitHub issue: https://github.com/asciinema/asciinema/issues/508 It works if I upload the small recording (195 bytes), but fails when I try to upload the 100 kB: ![image](https://user-images.githubusercontent.com/7887758/175268012-b7b5327f-9fee-4141-964c-86ee7633950d.png) The curl session return HTTP/2 500 code and says "Internal Server Error": ``` $ curl -v -u sskras:$(cat ~/.config/asciinema/install-id) https://asciinema.org/api/asciicasts -F asciicast=@/tmp/tmpqsscy294-ascii.cast; echo * Trying 109.107.37.0:443... * TCP_NODELAY set * Connected to asciinema.org (109.107.37.0) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256 * ALPN, server accepted to use h2 * Server certificate: * subject: CN=*.asciinema.org * start date: May 8 10:34:01 2022 GMT * expire date: Aug 6 10:34:00 2022 GMT * subjectAltName: host "asciinema.org" matched cert's "asciinema.org" * issuer: C=US; O=Let's Encrypt; CN=R3 * SSL certificate verify ok. * Using HTTP2, server supports multi-use * Connection state changed (HTTP/2 confirmed) * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Server auth using Basic with user 'sskras' * Using Stream ID: 1 (easy handle 0x55d77a0d9090) > POST /api/asciicasts HTTP/2 > Host: asciinema.org > authorization: Basic c3NrcmFzOjE4MTI2MjVmLTE4ODktNDE2Ni04ZWY2LTcxNDlkODFhMzEzOQ== > user-agent: curl/7.68.0 > accept: */* > content-length: 102619 > content-type: multipart/form-data; boundary=------------------------2e0590fa72362da5 > * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * Connection state changed (MAX_CONCURRENT_STREAMS == 250)! * We are completely uploaded and fine < HTTP/2 500 < cache-control: max-age=0, private, must-revalidate < content-type: text/plain; charset=utf-8 < date: Thu, 23 Jun 2022 09:37:24 GMT < server: nginx < x-request-id: Fvs2WRTm0Cq1it4EbE2i < content-length: 21 < * Connection #0 to host asciinema.org left intact Internal Server Error ``` Any ideas on how to proceed?
kerem closed this issue 2026-03-15 10:52:49 +03:00
Author
Owner

@sskras commented on GitHub (Jun 23, 2022):

I must admit that the bigger recording comes from the Asciinema crash due to the filled disk space.
The file was truncated, maybe its structure (the JSON?) is damaged. Just a thought.

<!-- gh-comment-id:1164186045 --> @sskras commented on GitHub (Jun 23, 2022): I must admit that the bigger recording comes from the Asciinema crash due to the filled disk space. The file was truncated, maybe its structure (the JSON?) is damaged. Just a thought.
Author
Owner

@sskras commented on GitHub (Jun 25, 2022):

OK, looks like it's supposed to be a multiline file containing JSONs separated by newlines:
https://blog.asciinema.org/#asciicast-v2-file-format

So I checked last line of the file:

$ tail -1 /tmp/tmpqsscy294-ascii.cast; echo "<EOF>"
[351.038637, "o", "without-pdo-firebird --without-pdo-mysql --without-pdo-oci --without-pdo-odbc --without-pdo-pgsql --wit<EOF>

So it really looks like it's truncated:

Now fixing end of the file and counting total lines:

$ { cat /tmp/tmpqsscy294-ascii.cast; echo; } | wc -l
886

... and doing a per-line check using jsonlint (from python3-demjson package):

$ time { cat /tmp/tmpqsscy294-ascii.cast; echo; } | while read LINE; do I=$((I+1)); echo $LINE | jsonlint -q || { echo -n "Line $I: "; echo $LINE | jsonlint; echo; } ; done
Line 886: <stdin>:1:122: Error: Line terminator characters must be escaped inside string literals: 'U+000A'
   |  At line 1, column 122, offset 122
   |  String started at line 1, column 18, offset 18
<stdin>:2:0: Error: String literal is not terminated
   |  At line 2, column 0, offset 123 (AT-END)
   |    near text: True
   |  String started at line 1, column 18, offset 18
<stdin>:2:0: Error: String literal is not terminated with a quotation mark
   |  At line 2, column 0, offset 123 (AT-END)
   |    near text: True
   |  String started at line 1, column 18, offset 18
<stdin>:2:0: Error: Array literal (list) is not terminated
   |  At line 2, column 0, offset 123 (AT-END)
   |    near text: True
   |  Array started at line 1, column 0, offset 0 (AT-START)
<stdin>: has errors


real    0m23.535s
user    0m19.403s
sys     0m4.968s

So the problem seems to be in the last line only.

<!-- gh-comment-id:1166244150 --> @sskras commented on GitHub (Jun 25, 2022): OK, looks like it's supposed to be a multiline file containing JSONs separated by newlines: https://blog.asciinema.org/#asciicast-v2-file-format So I checked last line of the file: ``` $ tail -1 /tmp/tmpqsscy294-ascii.cast; echo "<EOF>" [351.038637, "o", "without-pdo-firebird --without-pdo-mysql --without-pdo-oci --without-pdo-odbc --without-pdo-pgsql --wit<EOF> ``` So it really looks like it's truncated: Now fixing end of the file and counting total lines: ``` $ { cat /tmp/tmpqsscy294-ascii.cast; echo; } | wc -l 886 ``` ... and doing a per-line check using jsonlint (from _python3-demjson_ package): ``` $ time { cat /tmp/tmpqsscy294-ascii.cast; echo; } | while read LINE; do I=$((I+1)); echo $LINE | jsonlint -q || { echo -n "Line $I: "; echo $LINE | jsonlint; echo; } ; done Line 886: <stdin>:1:122: Error: Line terminator characters must be escaped inside string literals: 'U+000A' | At line 1, column 122, offset 122 | String started at line 1, column 18, offset 18 <stdin>:2:0: Error: String literal is not terminated | At line 2, column 0, offset 123 (AT-END) | near text: True | String started at line 1, column 18, offset 18 <stdin>:2:0: Error: String literal is not terminated with a quotation mark | At line 2, column 0, offset 123 (AT-END) | near text: True | String started at line 1, column 18, offset 18 <stdin>:2:0: Error: Array literal (list) is not terminated | At line 2, column 0, offset 123 (AT-END) | near text: True | Array started at line 1, column 0, offset 0 (AT-START) <stdin>: has errors real 0m23.535s user 0m19.403s sys 0m4.968s ``` So the problem seems to be in the last line only.
Author
Owner

@sskras commented on GitHub (Jun 25, 2022):

Making a copy:

$ cp -v /tmp/tmpqsscy294-ascii.cast .
'/tmp/tmpqsscy294-ascii.cast' -> './tmpqsscy294-ascii.cast'

Trying to fix:

$ echo " ...\"]" >> tmpqsscy294-ascii.cast
$ wc -l tmpqsscy294-ascii.cast
886 tmpqsscy294-ascii.cast

And voila, the error is gone:

$ time cat tmpqsscy294-ascii.cast | while read LINE; do I=$((I+1)); echo $LINE | jsonlint -q || { echo -n "Line $I: "; echo $LINE | jsonlint; echo; } ; done

real    0m23.513s
user    0m19.298s
sys     0m4.998s
<!-- gh-comment-id:1166244963 --> @sskras commented on GitHub (Jun 25, 2022): Making a copy: ``` $ cp -v /tmp/tmpqsscy294-ascii.cast . '/tmp/tmpqsscy294-ascii.cast' -> './tmpqsscy294-ascii.cast' ``` Trying to fix: ``` $ echo " ...\"]" >> tmpqsscy294-ascii.cast $ wc -l tmpqsscy294-ascii.cast 886 tmpqsscy294-ascii.cast ``` And voila, the error is gone: ``` $ time cat tmpqsscy294-ascii.cast | while read LINE; do I=$((I+1)); echo $LINE | jsonlint -q || { echo -n "Line $I: "; echo $LINE | jsonlint; echo; } ; done real 0m23.513s user 0m19.298s sys 0m4.998s ```
Author
Owner

@sskras commented on GitHub (Jun 25, 2022):

Now trying to upload the adjusted copy:

$ curl -v -u sskras:$(cat ~/.config/asciinema/install-id) https://asciinema.org/api/asciicasts -F asciicast=@./tmpqsscy294-ascii.cast; echo
*   Trying 109.107.38.233:443...
* TCP_NODELAY set
* Connected to asciinema.org (109.107.38.233) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=*.asciinema.org
*  start date: May  8 10:34:01 2022 GMT
*  expire date: Aug  6 10:34:00 2022 GMT
*  subjectAltName: host "asciinema.org" matched cert's "asciinema.org"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Server auth using Basic with user 'sskras'
* Using Stream ID: 1 (easy handle 0x557ba1f28090)
> POST /api/asciicasts HTTP/2
> Host: asciinema.org
> authorization: Basic c3NrcmFzOjE4MTI2MjVmLTE4ODktNDE2Ni04ZWY2LTcxNDlkODFhMzEzOQ==
> user-agent: curl/7.68.0
> accept: */*
> content-length: 102626
> content-type: multipart/form-data; boundary=------------------------6bc2e10c87f73d44
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
* We are completely uploaded and fine
< HTTP/2 201
< cache-control: max-age=0, private, must-revalidate
< content-type: text/plain; charset=utf-8
< date: Sat, 25 Jun 2022 09:55:12 GMT
< location: https://asciinema.org/a/5xzGJ3ddeftWXjc6Q8gZATwsk
< server: nginx
< strict-transport-security: max-age=15768000
< x-request-id: FvvUes30XezF4Q8EpfZy
< content-length: 78
<
View the recording at:

    https://asciinema.org/a/5xzGJ3ddeftWXjc6Q8gZATwsk
* Connection #0 to host asciinema.org left intact

Voila – it's here, on the server!

It would be nice if asciinema client had a functionality to fix the broken casts. Or at least to check their integrity.
Can this bugreport be left open with the latter request?

<!-- gh-comment-id:1166247674 --> @sskras commented on GitHub (Jun 25, 2022): Now trying to upload the adjusted copy: ``` $ curl -v -u sskras:$(cat ~/.config/asciinema/install-id) https://asciinema.org/api/asciicasts -F asciicast=@./tmpqsscy294-ascii.cast; echo * Trying 109.107.38.233:443... * TCP_NODELAY set * Connected to asciinema.org (109.107.38.233) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256 * ALPN, server accepted to use h2 * Server certificate: * subject: CN=*.asciinema.org * start date: May 8 10:34:01 2022 GMT * expire date: Aug 6 10:34:00 2022 GMT * subjectAltName: host "asciinema.org" matched cert's "asciinema.org" * issuer: C=US; O=Let's Encrypt; CN=R3 * SSL certificate verify ok. * Using HTTP2, server supports multi-use * Connection state changed (HTTP/2 confirmed) * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Server auth using Basic with user 'sskras' * Using Stream ID: 1 (easy handle 0x557ba1f28090) > POST /api/asciicasts HTTP/2 > Host: asciinema.org > authorization: Basic c3NrcmFzOjE4MTI2MjVmLTE4ODktNDE2Ni04ZWY2LTcxNDlkODFhMzEzOQ== > user-agent: curl/7.68.0 > accept: */* > content-length: 102626 > content-type: multipart/form-data; boundary=------------------------6bc2e10c87f73d44 > * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * Connection state changed (MAX_CONCURRENT_STREAMS == 250)! * We are completely uploaded and fine < HTTP/2 201 < cache-control: max-age=0, private, must-revalidate < content-type: text/plain; charset=utf-8 < date: Sat, 25 Jun 2022 09:55:12 GMT < location: https://asciinema.org/a/5xzGJ3ddeftWXjc6Q8gZATwsk < server: nginx < strict-transport-security: max-age=15768000 < x-request-id: FvvUes30XezF4Q8EpfZy < content-length: 78 < View the recording at: https://asciinema.org/a/5xzGJ3ddeftWXjc6Q8gZATwsk * Connection #0 to host asciinema.org left intact ``` Voila – it's here, on the server! It would be nice if `asciinema` client had a **functionality to fix the broken casts**. Or at least **to check their integrity**. Can this bugreport be left open with the latter request?
Author
Owner

@ku1ik commented on GitHub (Apr 15, 2023):

Glad you figured it out 👍

I don't think it's worth the extra work given user's full disk is not really asciinema's problem :)

<!-- gh-comment-id:1509876004 --> @ku1ik commented on GitHub (Apr 15, 2023): Glad you figured it out :+1: I don't think it's worth the extra work given user's full disk is not really asciinema's problem :)
Author
Owner

@sskras commented on GitHub (Apr 19, 2023):

@sickill, I partially disagree. Asciinema should:

(1) not crash when disk is full but exit gracefully;
(2) when crashing, it should handle the signal & tell that the output file is incomplete (in the stdout).

Should I file new issues about these points?

Then (3) web-service should output the human readable form of the error it encountered.
Not sure where is its repository / issue tracker.

<!-- gh-comment-id:1514584538 --> @sskras commented on GitHub (Apr 19, 2023): @sickill, I partially disagree. Asciinema should: (1) not crash when disk is full but exit gracefully; (2) when crashing, it should handle the signal & tell that the output file is incomplete (in the stdout). Should I file new issues about these points? Then (3) web-service should output the human readable form of the error it encountered. Not sure where is its repository / issue tracker.
Author
Owner

@ku1ik commented on GitHub (Apr 19, 2023):

In recently merged https://github.com/asciinema/asciinema/pull/545 I made it not crash, and instead show desktop notification "Write error, recording suspended". This should adress (1) and (2). It's doesn't immediately exit because you may be running some program whose interruption is undesired, so instead you get desktop notification and you can either continue your work / do cleanup, or just exit recorded program/shell immediately at your will.

Here's repo for the server component where we handle uploads: https://github.com/asciinema/asciinema-server/

<!-- gh-comment-id:1514630317 --> @ku1ik commented on GitHub (Apr 19, 2023): In recently merged https://github.com/asciinema/asciinema/pull/545 I made it not crash, and instead show desktop notification "Write error, recording suspended". This should adress (1) and (2). It's doesn't immediately exit because you may be running some program whose interruption is undesired, so instead you get desktop notification and you can either continue your work / do cleanup, or just exit recorded program/shell immediately at your will. Here's repo for the server component where we handle uploads: https://github.com/asciinema/asciinema-server/
Author
Owner

@sskras commented on GitHub (Apr 20, 2023):

Thanks for the details!

<!-- gh-comment-id:1515943863 --> @sskras commented on GitHub (Apr 20, 2023): Thanks for the details!
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/asciinema#894
No description provided.