I asked the question about downloading of files upon submitting a form.

Now I want to clarify how to do it in the case of controller function. That is, some controller is called and its function is being executed.

In the form submit function file downloading starts upon executing the $form_state->setResponse($response);

How to start it in the controller function ?

I tried to use $response->send(); but it sends a file with wrong data and another size.

3 Answers 3


Never send the response with $response->send(). Instead return the response:

use Symfony\Component\HttpFoundation\Response;

public function myController() {
    $response = new Response();
    // prepare $response
    return $response;

BTW, this is a standard Symfony Controller. The fact that you also can return the main content in a render array is because Drupal has added an event subscriber, which converts the main content to a response with the themed html page.

This works for all responses, in your case for example for a binary file response:


  public function download(Request $request, $scheme = 'private') {
    $target = $request->query->get('file');
    // Merge remaining path arguments into relative file path.
    $uri = $scheme . '://' . $target;

    if (file_stream_wrapper_valid_scheme($scheme) && file_exists($uri)) {
      // Let other modules provide headers and controls access to the file.
      $headers = $this->moduleHandler()->invokeAll('file_download', [$uri]);

      foreach ($headers as $result) {
        if ($result == -1) {
          throw new AccessDeniedHttpException();

      if (count($headers)) {
        // \Drupal\Core\EventSubscriber\FinishResponseSubscriber::onRespond()
        // sets response as not cacheable if the Cache-Control header is not
        // already modified. We pass in FALSE for non-private schemes for the
        // $public parameter to make sure we don't change the headers.
        return new BinaryFileResponse($uri, 200, $headers, $scheme !== 'private');

      throw new AccessDeniedHttpException();

    throw new NotFoundHttpException();
  • 1
    Would want BinaryFileResponse though?
    – Kevin
    Commented Sep 8, 2017 at 6:51
  • 1
    @Kevin, yes, you can return any kind of response. I've added this as example.
    – 4uk4
    Commented Sep 8, 2017 at 6:57
  • 2
    Are cache headers added to that automatically?
    – Brian
    Commented Aug 8, 2018 at 18:28

My way in Drupal 8 controller;

use Symfony\Component\HttpFoundation\BinaryFileResponse;

$uri = 'public://' . $fileName;

$headers = array(
        'Content-Type'     => 'application/pdf',
        'Content-Disposition' => 'attachment;filename="'.$fileName.'"');

return new BinaryFileResponse($uri, 200, $headers, true);
  • 5
    Welcome to Drupal Answers! We always intend to provide good quality answers that will help the original questioner as well as others that might find this question/answer when searching with similar issues. Your answer does not quite meet these requirements. If you find that your answer adds to the already existing answer, please re-edit, providing more context and a better code snippet that highlights where to apply the statements. Also have a check of the Drupal Coding Standards (drupal.org/docs/develop/standards/coding-standards) and use proper indendation in your code snippets. Commented Mar 4, 2019 at 2:03
  • 3
    I appreciate the succinct nature of this answer.
    – ummdorian
    Commented Oct 31, 2019 at 3:01
  • 2
    Great answer, what I have been looking for, for hours!
    – Jaeger
    Commented Jul 1, 2020 at 13:33

Piggybacking on Tien Wang's answer, here is an example using a file entity:

$headers = array(
  'Content-Type' => $file->getMimeType(),
  'Content-Disposition' => 'attachment;filename="'.$file->getFilename().'"',
  'Content-Length' => $file->getSize(),
  'Content-Description' => ' File Transfer'

return new BinaryFileResponse($file->getFileUri(), 200, $headers, true);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.